Index: mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -340,9 +340,9 @@ } if (auto invOp = dyn_cast(opInst)) { - auto operands = moduleTranslation.lookupValues(opInst.getOperands()); + auto operands = moduleTranslation.lookupValues(invOp.getCalleeOperands()); ArrayRef operandsRef(operands); - llvm::Value *result; + llvm::Instruction *result; if (auto attr = opInst.getAttrOfType("callee")) { result = builder.CreateInvoke( moduleTranslation.lookupFunction(attr.getValue()), @@ -359,6 +359,7 @@ moduleTranslation.lookupBlock(invOp.getSuccessor(1)), operandsRef.drop_front()); } + moduleTranslation.mapBranch(invOp, result); // InvokeOp can only have 0 or 1 result if (invOp->getNumResults() != 0) { moduleTranslation.mapValue(opInst.getResult(0), result); Index: mlir/lib/Target/LLVMIR/ModuleTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -386,8 +386,15 @@ return switchOp.getCaseOperands(i.index())[index]; } - llvm_unreachable("only branch or switch operations can be terminators of a " - "block that has successors"); + if (auto invokeOp = dyn_cast(terminator)) { + return invokeOp.getNormalDest() == current + ? invokeOp.getNormalDestOperands()[index] + : invokeOp.getUnwindDestOperands()[index]; + } + + llvm_unreachable( + "only branch, switch or invoke operations can be terminators " + "of a block that has successors"); } /// Connect the PHI nodes to the results of preceding blocks. Index: mlir/test/Target/LLVMIR/llvmir.mlir =================================================================== --- mlir/test/Target/LLVMIR/llvmir.mlir +++ mlir/test/Target/LLVMIR/llvmir.mlir @@ -1326,6 +1326,34 @@ // ----- +llvm.func @foo() +llvm.func @__gxx_personality_v0(...) -> i32 + +// CHECK-LABEL: @invoke_phis +llvm.func @invoke_phis() -> i32 attributes { personality = @__gxx_personality_v0 } { +// CHECK: invoke void @foo() +// CHECK-NEXT: to label %[[normal:[0-9]+]] unwind label %[[unwind:[0-9]+]] + %0 = llvm.mlir.constant(0 : i32) : i32 + llvm.invoke @foo() to ^bb1(%0 : i32) unwind ^bb2 : () -> () + +// CHECK: [[normal]]: +// CHECK-NEXT: %[[a1:[0-9]+]] = phi i32 [ 1, %[[unwind]] ], [ 0, %0 ] +// CHECK-NEXT: ret i32 %[[a1]] +^bb1(%1 : i32): + llvm.return %1 : i32 + +// CHECK: [[unwind]]: +// CHECK-NEXT: landingpad { i8*, i32 } +// CHECK-NEXT: cleanup +// CHECK-NEXT: br label %[[normal]] +^bb2: + %2 = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)> + %3 = llvm.mlir.constant(1 : i32) : i32 + llvm.br ^bb1(%3 : i32) +} + +// ----- + // CHECK-LABEL: @callFreezeOp llvm.func @callFreezeOp(%x : i32) { // CHECK: freeze i32 %{{[0-9]+}}