From 560972052a25ada0efd47ddaf21ece1cd286ae65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6ck?= Date: Thu, 6 Jan 2022 00:41:35 +0100 Subject: [PATCH] [mlir][LLVM] Implement mapping of phi source values of `llvm.invoke` This patch allows the usage of the normalDestOperands and unwindDestOperands operands of llvm.invoke and have them be correctly mapped to phis in the successor when exported to LLVM IR. Differential Revision: https://reviews.llvm.org/D116706 --- .../LLVMIR/LLVMToLLVMIRTranslation.cpp | 5 ++-- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 11 ++++++-- mlir/test/Target/LLVMIR/llvmir.mlir | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp index 3254aed6c341..e4932e84cd28 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -340,9 +340,9 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, } 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 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, 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); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 404018bebe93..1ca3fb2fc664 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -386,8 +386,15 @@ static Value getPHISourceValue(Block *current, Block *pred, 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. diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 6741d51b5f39..54dfd519d81c 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -1326,6 +1326,34 @@ llvm.func @invoke_result(%arg0 : !llvm.ptr) attributes { personality = @__gx // ----- +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]+}}