Skip to content

Commit af822e2

Browse files
authored
[MLIR] Allow llvm.resume with non-landingpad input (#8590)
This changes verification of llvm.resume to just fail if there is no llvm.landingpad instruction in the same function with the same type as this instruction's input, more in line with LLVM's verification. From LLVM documentation (https://llvm.org/docs/LangRef.html#i-resume): The ‘resume’ instruction requires one argument, which must have the same type as the result of any ‘landingpad’ instruction in the same function. Signed-off-by: Victor Perez <victor.perez@codeplay.com>
1 parent f8f6916 commit af822e2

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,8 +1585,21 @@ LogicalResult ReturnOp::verify() {
15851585
//===----------------------------------------------------------------------===//
15861586

15871587
LogicalResult ResumeOp::verify() {
1588-
if (!getValue().getDefiningOp<LandingpadOp>())
1589-
return emitOpError("expects landingpad value as operand");
1588+
auto parentFunc = getOperation()->getParentOfType<FunctionOpInterface>();
1589+
assert(parentFunc && "Expecting parent function");
1590+
const auto ty = getOperand().getType();
1591+
if (!parentFunc
1592+
->walk([ty](LandingpadOp landingpad) {
1593+
return landingpad.getType() == ty
1594+
? WalkResult::interrupt() // Just an operation needed
1595+
: WalkResult::advance();
1596+
})
1597+
.wasInterrupted()) {
1598+
// No operation was found: emit error
1599+
return emitOpError("expects landingpad operation in the same function and "
1600+
"with the same type as this operation's operand");
1601+
}
1602+
15901603
// No check for personality of function - landingpad op verifies it.
15911604
return success();
15921605
}

mlir/test/Dialect/LLVMIR/invalid.mlir

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,18 @@ llvm.func @caller(%arg0: i32) -> i32 attributes { personality = @__gxx_personali
810810
llvm.return %0 : i32
811811
^bb2: // pred: ^bb0
812812
%2 = llvm.landingpad cleanup : !llvm.struct<(ptr<i8>, i32)>
813-
// expected-error@+1 {{'llvm.resume' op expects landingpad value as operand}}
813+
// expected-error@+1 {{'llvm.resume' op expects landingpad operation in the same function and with the same type as this operation's operand}}
814+
llvm.resume %0 : i32
815+
}
816+
817+
// -----
818+
819+
llvm.func @foo(i32) -> i32
820+
llvm.func @__gxx_personality_v0(...) -> i32
821+
822+
llvm.func @caller(%arg0: i32) -> i32 attributes { personality = @__gxx_personality_v0 } {
823+
%0 = llvm.mlir.constant(1 : i32) : i32
824+
// expected-error@+1 {{'llvm.resume' op expects landingpad operation in the same function and with the same type as this operation's operand}}
814825
llvm.resume %0 : i32
815826
}
816827

mlir/test/Dialect/LLVMIR/roundtrip.mlir

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,27 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
425425
llvm.return %0 : i32
426426
}
427427

428+
llvm.func @foo2() -> !llvm.struct<(ptr<i8>, i32)>
429+
430+
// CHECK-LABEL: llvm.func @resumeNoLandingpadValue(
431+
// CHECK-SAME: %[[ARG:.*]]: i32)
432+
llvm.func @resumeNoLandingpadValue(%arg0: i32) -> i32 attributes { personality = @__gxx_personality_v0 } {
433+
// CHECK: %[[VAL_0:.*]] = llvm.call @foo2() : () -> !llvm.struct<(ptr<i8>, i32)>
434+
// CHECK: %[[VAL_1:.*]] = llvm.invoke @foo(%[[ARG]]) to ^[[BB1:.*]] unwind ^[[BB2:.*]] : (i32) -> i32
435+
%0 = llvm.call @foo2() : () -> !llvm.struct<(ptr<i8>, i32)>
436+
%1 = llvm.invoke @foo(%arg0) to ^bb1 unwind ^bb2 : (i32) -> i32
437+
// CHECK: ^[[BB1]]:
438+
// CHECK: llvm.return %[[VAL_1]] : i32
439+
^bb1: // pred: ^bb0
440+
llvm.return %1 : i32
441+
// CHECK: ^[[BB2]]:
442+
// CHECK: %[[VAL_2:.*]] = llvm.landingpad cleanup : !llvm.struct<(ptr<i8>, i32)>
443+
// CHECK: llvm.resume %[[VAL_0]] : !llvm.struct<(ptr<i8>, i32)>
444+
^bb2: // pred: ^bb0
445+
%2 = llvm.landingpad cleanup : !llvm.struct<(ptr<i8>, i32)>
446+
llvm.resume %0 : !llvm.struct<(ptr<i8>, i32)>
447+
}
448+
428449
// CHECK-LABEL: @useFreezeOp
429450
func.func @useFreezeOp(%arg0: i32) {
430451
// CHECK: = llvm.freeze %[[ARG0:.*]] : i32

0 commit comments

Comments
 (0)