Skip to content

Commit b68070a

Browse files
committed
update blocks
1 parent a462d78 commit b68070a

File tree

8 files changed

+230
-24
lines changed

8 files changed

+230
-24
lines changed

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,28 +135,28 @@ def int_wasm_uzumaki_i64 :
135135
// transforms into proper blocks
136136

137137
def int_wasm_forall_start :
138-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
138+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
139139

140140
def int_wasm_forall_end :
141-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
141+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
142142

143143
def int_wasm_exists_start :
144-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
144+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
145145

146146
def int_wasm_exists_end :
147-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
147+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
148148

149149
def int_wasm_assume_start :
150-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
150+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
151151

152152
def int_wasm_assume_end :
153-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
153+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
154154

155155
def int_wasm_unique_start :
156-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
156+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
157157

158158
def int_wasm_unique_end :
159-
DefaultAttrsIntrinsic<[], [], [IntrNoMem]>;
159+
DefaultAttrsIntrinsic<[], [], [IntrHasSideEffects]>;
160160

161161
//===----------------------------------------------------------------------===//
162162
// Exception handling intrinsics

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3428,6 +3428,28 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
34283428
DAG.setRoot(DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops));
34293429
break;
34303430
}
3431+
// Inference block intrinsics: handle them like wasm_throw/wasm_rethrow
3432+
// to prevent crashes in visitTargetIntrinsic
3433+
case Intrinsic::wasm_forall_start:
3434+
case Intrinsic::wasm_forall_end:
3435+
case Intrinsic::wasm_exists_start:
3436+
case Intrinsic::wasm_exists_end:
3437+
case Intrinsic::wasm_assume_start:
3438+
case Intrinsic::wasm_assume_end:
3439+
case Intrinsic::wasm_unique_start:
3440+
case Intrinsic::wasm_unique_end: {
3441+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
3442+
unsigned IntrID = cast<IntrinsicInst>(I).getIntrinsicID();
3443+
llvm::errs() << "DEBUG: Special handling for inference block intrinsic " << IntrID << "\n";
3444+
std::array<SDValue, 2> Ops = {
3445+
getControlRoot(), // inchain for the terminator node
3446+
DAG.getTargetConstant(IntrID, getCurSDLoc(),
3447+
TLI.getPointerTy(DAG.getDataLayout()))};
3448+
SDVTList VTs = DAG.getVTList(ArrayRef<EVT>({MVT::Other})); // outchain
3449+
llvm::errs() << "DEBUG: Creating INTRINSIC_VOID node for instruction selection\n";
3450+
DAG.setRoot(DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops));
3451+
break;
3452+
}
34313453
}
34323454
} else if (I.hasDeoptState()) {
34333455
// Currently we do not lower any intrinsic calls with deopt operand bundles.

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -656,26 +656,26 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
656656
break;
657657
}
658658
// Inference block instructions
659-
case WebAssembly::BLOCK_FORALL: {
659+
case WebAssembly::INFERENCE_FORALL: {
660660
OutStreamer->emitIntValue(0xFC, 1);
661661
OutStreamer->emitIntValue(0x3A, 1);
662662
// Emit block type (0x40 for void)
663663
OutStreamer->emitIntValue(0x40, 1);
664664
break;
665665
}
666-
case WebAssembly::BLOCK_EXISTS: {
666+
case WebAssembly::INFERENCE_EXISTS: {
667667
OutStreamer->emitIntValue(0xFC, 1);
668668
OutStreamer->emitIntValue(0x3B, 1);
669669
OutStreamer->emitIntValue(0x40, 1);
670670
break;
671671
}
672-
case WebAssembly::BLOCK_ASSUME: {
672+
case WebAssembly::INFERENCE_ASSUME: {
673673
OutStreamer->emitIntValue(0xFC, 1);
674674
OutStreamer->emitIntValue(0x3C, 1);
675675
OutStreamer->emitIntValue(0x40, 1);
676676
break;
677677
}
678-
case WebAssembly::BLOCK_UNIQUE: {
678+
case WebAssembly::INFERENCE_UNIQUE: {
679679
OutStreamer->emitIntValue(0xFC, 1);
680680
OutStreamer->emitIntValue(0x3D, 1);
681681
OutStreamer->emitIntValue(0x40, 1);

llvm/lib/Target/WebAssembly/WebAssemblyISD.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ HANDLE_NODETYPE(BLOCK_FORALL)
5555
HANDLE_NODETYPE(BLOCK_EXISTS)
5656
HANDLE_NODETYPE(BLOCK_ASSUME)
5757
HANDLE_NODETYPE(BLOCK_UNIQUE)
58+
HANDLE_NODETYPE(BLOCK_FORALL_END)
59+
HANDLE_NODETYPE(BLOCK_EXISTS_END)
60+
HANDLE_NODETYPE(BLOCK_ASSUME_END)
61+
HANDLE_NODETYPE(BLOCK_UNIQUE_END)
5862

5963
// Memory intrinsics
6064
HANDLE_NODETYPE(GLOBAL_GET)

llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
232232

233233
case ISD::INTRINSIC_VOID: {
234234
unsigned IntNo = Node->getConstantOperandVal(1);
235+
llvm::errs() << "DEBUG: INTRINSIC_VOID instruction selection for intrinsic " << IntNo << "\n";
235236
switch (IntNo) {
236237
case Intrinsic::wasm_throw: {
237238
int Tag = Node->getConstantOperandVal(2);
@@ -260,10 +261,159 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
260261
ReplaceNode(Node, Rethrow);
261262
return;
262263
}
264+
265+
// Inference block intrinsics
266+
case Intrinsic::wasm_forall_start: {
267+
llvm::errs() << "DEBUG: Custom instruction selection for wasm_forall_start\n";
268+
MachineSDNode *ForallStart = CurDAG->getMachineNode(
269+
WebAssembly::INFERENCE_FORALL, DL,
270+
MVT::Other, // outchain type
271+
Node->getOperand(0) // inchain
272+
);
273+
ReplaceNode(Node, ForallStart);
274+
return;
275+
}
276+
case Intrinsic::wasm_exists_start: {
277+
MachineSDNode *ExistsStart = CurDAG->getMachineNode(
278+
WebAssembly::INFERENCE_EXISTS, DL,
279+
MVT::Other, // outchain type
280+
Node->getOperand(0) // inchain
281+
);
282+
ReplaceNode(Node, ExistsStart);
283+
return;
284+
}
285+
case Intrinsic::wasm_assume_start: {
286+
MachineSDNode *AssumeStart = CurDAG->getMachineNode(
287+
WebAssembly::INFERENCE_ASSUME, DL,
288+
MVT::Other, // outchain type
289+
Node->getOperand(0) // inchain
290+
);
291+
ReplaceNode(Node, AssumeStart);
292+
return;
293+
}
294+
case Intrinsic::wasm_unique_start: {
295+
MachineSDNode *UniqueStart = CurDAG->getMachineNode(
296+
WebAssembly::INFERENCE_UNIQUE, DL,
297+
MVT::Other, // outchain type
298+
Node->getOperand(0) // inchain
299+
);
300+
ReplaceNode(Node, UniqueStart);
301+
return;
302+
}
303+
case Intrinsic::wasm_forall_end: {
304+
MachineSDNode *ForallEnd = CurDAG->getMachineNode(
305+
WebAssembly::INFERENCE_FORALL_END, DL,
306+
MVT::Other, // outchain type
307+
Node->getOperand(0) // inchain
308+
);
309+
ReplaceNode(Node, ForallEnd);
310+
return;
311+
}
312+
case Intrinsic::wasm_exists_end: {
313+
MachineSDNode *ExistsEnd = CurDAG->getMachineNode(
314+
WebAssembly::INFERENCE_EXISTS_END, DL,
315+
MVT::Other, // outchain type
316+
Node->getOperand(0) // inchain
317+
);
318+
ReplaceNode(Node, ExistsEnd);
319+
return;
320+
}
321+
case Intrinsic::wasm_assume_end: {
322+
MachineSDNode *AssumeEnd = CurDAG->getMachineNode(
323+
WebAssembly::INFERENCE_ASSUME_END, DL,
324+
MVT::Other, // outchain type
325+
Node->getOperand(0) // inchain
326+
);
327+
ReplaceNode(Node, AssumeEnd);
328+
return;
329+
}
330+
case Intrinsic::wasm_unique_end: {
331+
MachineSDNode *UniqueEnd = CurDAG->getMachineNode(
332+
WebAssembly::INFERENCE_UNIQUE_END, DL,
333+
MVT::Other, // outchain type
334+
Node->getOperand(0) // inchain
335+
);
336+
ReplaceNode(Node, UniqueEnd);
337+
return;
338+
}
263339
}
264340
break;
265341
}
266342

343+
344+
// Inference block instructions
345+
case WebAssemblyISD::BLOCK_FORALL: {
346+
MachineSDNode *ForallStart = CurDAG->getMachineNode(
347+
WebAssembly::INFERENCE_FORALL, DL,
348+
MVT::Other, // outchain type
349+
Node->getOperand(0) // inchain
350+
);
351+
ReplaceNode(Node, ForallStart);
352+
return;
353+
}
354+
case WebAssemblyISD::BLOCK_EXISTS: {
355+
MachineSDNode *ExistsStart = CurDAG->getMachineNode(
356+
WebAssembly::INFERENCE_EXISTS, DL,
357+
MVT::Other, // outchain type
358+
Node->getOperand(0) // inchain
359+
);
360+
ReplaceNode(Node, ExistsStart);
361+
return;
362+
}
363+
case WebAssemblyISD::BLOCK_ASSUME: {
364+
MachineSDNode *AssumeStart = CurDAG->getMachineNode(
365+
WebAssembly::INFERENCE_ASSUME, DL,
366+
MVT::Other, // outchain type
367+
Node->getOperand(0) // inchain
368+
);
369+
ReplaceNode(Node, AssumeStart);
370+
return;
371+
}
372+
case WebAssemblyISD::BLOCK_UNIQUE: {
373+
MachineSDNode *UniqueStart = CurDAG->getMachineNode(
374+
WebAssembly::INFERENCE_UNIQUE, DL,
375+
MVT::Other, // outchain type
376+
Node->getOperand(0) // inchain
377+
);
378+
ReplaceNode(Node, UniqueStart);
379+
return;
380+
}
381+
case WebAssemblyISD::BLOCK_FORALL_END: {
382+
MachineSDNode *ForallEnd = CurDAG->getMachineNode(
383+
WebAssembly::INFERENCE_FORALL_END, DL,
384+
MVT::Other, // outchain type
385+
Node->getOperand(0) // inchain
386+
);
387+
ReplaceNode(Node, ForallEnd);
388+
return;
389+
}
390+
case WebAssemblyISD::BLOCK_EXISTS_END: {
391+
MachineSDNode *ExistsEnd = CurDAG->getMachineNode(
392+
WebAssembly::INFERENCE_EXISTS_END, DL,
393+
MVT::Other, // outchain type
394+
Node->getOperand(0) // inchain
395+
);
396+
ReplaceNode(Node, ExistsEnd);
397+
return;
398+
}
399+
case WebAssemblyISD::BLOCK_ASSUME_END: {
400+
MachineSDNode *AssumeEnd = CurDAG->getMachineNode(
401+
WebAssembly::INFERENCE_ASSUME_END, DL,
402+
MVT::Other, // outchain type
403+
Node->getOperand(0) // inchain
404+
);
405+
ReplaceNode(Node, AssumeEnd);
406+
return;
407+
}
408+
case WebAssemblyISD::BLOCK_UNIQUE_END: {
409+
MachineSDNode *UniqueEnd = CurDAG->getMachineNode(
410+
WebAssembly::INFERENCE_UNIQUE_END, DL,
411+
MVT::Other, // outchain type
412+
Node->getOperand(0) // inchain
413+
);
414+
ReplaceNode(Node, UniqueEnd);
415+
return;
416+
}
267417
case WebAssemblyISD::CALL:
268418
case WebAssemblyISD::RET_CALL: {
269419
// CALL has both variable operands and variable results, but ISel only

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,23 +2216,23 @@ SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
22162216
case Intrinsic::wasm_uzumaki_i64:
22172217
return DAG.getNode(WebAssemblyISD::UZUMAKI_I64, DL, MVT::i64);
22182218

2219-
// Inference block start markers
2219+
// Inference block intrinsics - lower to WebAssemblyISD nodes
22202220
case Intrinsic::wasm_forall_start:
22212221
return DAG.getNode(WebAssemblyISD::BLOCK_FORALL, DL, MVT::Other, Op.getOperand(0));
2222+
case Intrinsic::wasm_forall_end:
2223+
return DAG.getNode(WebAssemblyISD::BLOCK_FORALL_END, DL, MVT::Other, Op.getOperand(0));
22222224
case Intrinsic::wasm_exists_start:
22232225
return DAG.getNode(WebAssemblyISD::BLOCK_EXISTS, DL, MVT::Other, Op.getOperand(0));
2226+
case Intrinsic::wasm_exists_end:
2227+
return DAG.getNode(WebAssemblyISD::BLOCK_EXISTS_END, DL, MVT::Other, Op.getOperand(0));
22242228
case Intrinsic::wasm_assume_start:
22252229
return DAG.getNode(WebAssemblyISD::BLOCK_ASSUME, DL, MVT::Other, Op.getOperand(0));
2230+
case Intrinsic::wasm_assume_end:
2231+
return DAG.getNode(WebAssemblyISD::BLOCK_ASSUME_END, DL, MVT::Other, Op.getOperand(0));
22262232
case Intrinsic::wasm_unique_start:
22272233
return DAG.getNode(WebAssemblyISD::BLOCK_UNIQUE, DL, MVT::Other, Op.getOperand(0));
2228-
2229-
// Block end markers are lowered to standard WASM 'end' instruction
2230-
case Intrinsic::wasm_forall_end:
2231-
case Intrinsic::wasm_exists_end:
2232-
case Intrinsic::wasm_assume_end:
22332234
case Intrinsic::wasm_unique_end:
2234-
// These are handled as part of block scope management
2235-
return Op.getOperand(0); // Just pass through the chain
2235+
return DAG.getNode(WebAssemblyISD::BLOCK_UNIQUE_END, DL, MVT::Other, Op.getOperand(0));
22362236

22372237
case Intrinsic::wasm_lsda: {
22382238
auto PtrVT = getPointerTy(MF.getDataLayout());

llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,22 @@ defm BLOCK_UNIQUE : NRI<(outs), (ins Signature:$sig),
237237
[],
238238
"block.unique\t$sig", 0x00>;
239239
}
240+
241+
// Inference block instructions: side-effect operations like exception handling
242+
let hasCtrlDep = 1, hasSideEffects = 1, Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
243+
defm INFERENCE_FORALL : NRI<(outs), (ins), [], "forall", 0x00>;
244+
defm INFERENCE_EXISTS : NRI<(outs), (ins), [], "exists", 0x00>;
245+
defm INFERENCE_ASSUME : NRI<(outs), (ins), [], "assume", 0x00>;
246+
defm INFERENCE_UNIQUE : NRI<(outs), (ins), [], "unique", 0x00>;
247+
248+
// End markers for inference blocks (generate regular 'end' instruction)
249+
defm INFERENCE_FORALL_END : NRI<(outs), (ins), [], "end", 0x0b>;
250+
defm INFERENCE_EXISTS_END : NRI<(outs), (ins), [], "end", 0x0b>;
251+
defm INFERENCE_ASSUME_END : NRI<(outs), (ins), [], "end", 0x0b>;
252+
defm INFERENCE_UNIQUE_END : NRI<(outs), (ins), [], "end", 0x0b>;
253+
}
254+
255+
// Patterns to connect chain-based SDNodes to inference block instructions
256+
// Note: These patterns expect chain inputs but our instructions have no operands
257+
// This approach may need a different strategy
258+

llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def SDT_WebAssemblyGlobalGet : SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>;
115115
def SDT_WebAssemblyGlobalSet : SDTypeProfile<0, 2, [SDTCisPtrTy<1>]>;
116116
def SDT_WebAssemblyUzumakiI32 : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>;
117117
def SDT_WebAssemblyUzumakiI64 : SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;
118+
def SDT_WebAssemblyChainVoid : SDTypeProfile<1, 1, []>;
118119

119120
//===----------------------------------------------------------------------===//
120121
// WebAssembly-specific DAG Nodes.
@@ -151,13 +152,23 @@ def WebAssemblyuzumaki_i64 : SDNode<"WebAssemblyISD::UZUMAKI_I64",
151152

152153
// Inference block SDNodes
153154
def WebAssemblyforall_start : SDNode<"WebAssemblyISD::BLOCK_FORALL",
154-
SDTNone, [SDNPHasChain]>;
155+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
155156
def WebAssemblyexists_start : SDNode<"WebAssemblyISD::BLOCK_EXISTS",
156-
SDTNone, [SDNPHasChain]>;
157+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
157158
def WebAssemblyassume_start : SDNode<"WebAssemblyISD::BLOCK_ASSUME",
158-
SDTNone, [SDNPHasChain]>;
159+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
159160
def WebAssemblyunique_start : SDNode<"WebAssemblyISD::BLOCK_UNIQUE",
160-
SDTNone, [SDNPHasChain]>;
161+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
162+
163+
// Inference block end markers (use regular 'end' instruction)
164+
def WebAssemblyforall_end : SDNode<"WebAssemblyISD::BLOCK_FORALL_END",
165+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
166+
def WebAssemblyexists_end : SDNode<"WebAssemblyISD::BLOCK_EXISTS_END",
167+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
168+
def WebAssemblyassume_end : SDNode<"WebAssemblyISD::BLOCK_ASSUME_END",
169+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
170+
def WebAssemblyunique_end : SDNode<"WebAssemblyISD::BLOCK_UNIQUE_END",
171+
SDT_WebAssemblyChainVoid, [SDNPHasChain]>;
161172

162173
def WebAssemblylocal_get :
163174
SDNode<"WebAssemblyISD::LOCAL_GET", SDT_WebAssemblyLocalGet,

0 commit comments

Comments
 (0)