1; RUN: mlir-translate -import-llvm %s | FileCheck %s 2 3@_ZTIi = external dso_local constant ptr 4@_ZTIii= external dso_local constant ptr 5declare void @foo(ptr) 6declare void @vararg_foo(ptr, ...) 7declare ptr @bar(ptr) 8declare i32 @__gxx_personality_v0(...) 9 10; CHECK-LABEL: @invokeLandingpad 11define i32 @invokeLandingpad() personality ptr @__gxx_personality_v0 { 12 ; CHECK: %[[a1:[0-9]+]] = llvm.mlir.addressof @_ZTIii : !llvm.ptr 13 ; CHECK: %[[a3:[0-9]+]] = llvm.alloca %{{[0-9]+}} x i8 {alignment = 1 : i64} : (i32) -> !llvm.ptr 14 %1 = alloca i8 15 ; CHECK: llvm.invoke @foo(%[[a3]]) to ^[[bb1:.*]] unwind ^[[bb4:.*]] : (!llvm.ptr) -> () 16 invoke void @foo(ptr %1) to label %bb1 unwind label %bb4 17 18; CHECK: ^[[bb1]]: 19bb1: 20 ; CHECK: %{{[0-9]+}} = llvm.invoke @bar(%[[a3]]) to ^[[bb2:.*]] unwind ^[[bb4]] : (!llvm.ptr) -> !llvm.ptr 21 %2 = invoke ptr @bar(ptr %1) to label %bb2 unwind label %bb4 22 23; CHECK: ^[[bb2]]: 24bb2: 25 ; CHECK: llvm.invoke @vararg_foo(%[[a3]], %{{.*}}) to ^[[bb3:.*]] unwind ^[[bb4]] vararg(!llvm.func<void (ptr, ...)>) : (!llvm.ptr, i32) -> () 26 invoke void (ptr, ...) @vararg_foo(ptr %1, i32 0) to label %bb3 unwind label %bb4 27 28; CHECK: ^[[bb3]]: 29bb3: 30 ; CHECK: llvm.invoke %{{.*}}(%[[a3]], %{{.*}}) to ^[[bb5:.*]] unwind ^[[bb4]] vararg(!llvm.func<void (ptr, ...)>) : !llvm.ptr, (!llvm.ptr, i32) -> () 31 invoke void (ptr, ...) undef(ptr %1, i32 0) to label %bb5 unwind label %bb4 32 33; CHECK: ^[[bb4]]: 34bb4: 35 ; CHECK: %{{[0-9]+}} = llvm.landingpad (catch %{{[0-9]+}} : !llvm.ptr) (catch %[[a1]] : !llvm.ptr) (filter %{{[0-9]+}} : !llvm.array<1 x i1>) : !llvm.struct<(ptr, i32)> 36 %3 = landingpad { ptr, i32 } catch ptr @_ZTIi catch ptr @_ZTIii 37 filter [1 x i1] [i1 1] 38 resume { ptr, i32 } %3 39 40; CHECK: ^[[bb5]]: 41bb5: 42 ; CHECK: llvm.return %{{[0-9]+}} : i32 43 ret i32 1 44} 45 46declare i32 @foo2() 47 48; CHECK-LABEL: @invokePhi 49; CHECK-SAME: (%[[cond:.*]]: i1) -> i32 50define i32 @invokePhi(i1 %cond) personality ptr @__gxx_personality_v0 { 51entry: 52 ; CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : i32) : i32 53 ; CHECK: llvm.cond_br %[[cond]], ^[[bb1:.*]], ^[[bb2:.*]] 54 br i1 %cond, label %call, label %nocall 55; CHECK: ^[[bb1]]: 56call: 57 ; CHECK: %[[invoke:.*]] = llvm.invoke @foo2() to ^[[bb3:.*]] unwind ^[[bb5:.*]] : () -> i32 58 %invoke = invoke i32 @foo2() to label %bb0 unwind label %bb1 59; CHECK: ^[[bb2]]: 60nocall: 61 ; CHECK: llvm.br ^[[bb4:.*]](%[[c0]] : i32) 62 br label %bb0 63; CHECK: ^[[bb3]]: 64 ; CHECK: llvm.br ^[[bb4]](%[[invoke]] : i32) 65; CHECK: ^[[bb4]](%[[barg:.*]]: i32): 66bb0: 67 %ret = phi i32 [ 0, %nocall ], [ %invoke, %call ] 68 ; CHECK: llvm.return %[[barg]] : i32 69 ret i32 %ret 70; CHECK: ^[[bb5]]: 71bb1: 72 ; CHECK: %[[lp:.*]] = llvm.landingpad cleanup : i32 73 %resume = landingpad i32 cleanup 74 ; CHECK: llvm.resume %[[lp]] : i32 75 resume i32 %resume 76} 77 78; CHECK-LABEL: @invokePhiComplex 79; CHECK-SAME: (%[[cond:.*]]: i1) -> i32 80define i32 @invokePhiComplex(i1 %cond) personality ptr @__gxx_personality_v0 { 81entry: 82 ; CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : i32) : i32 83 ; CHECK: %[[c1:.*]] = llvm.mlir.constant(1 : i32) : i32 84 ; CHECK: %[[c2:.*]] = llvm.mlir.constant(2 : i32) : i32 85 ; CHECK: %[[c20:.*]] = llvm.mlir.constant(20 : i32) : i32 86 ; CHECK: llvm.cond_br %[[cond]], ^[[bb1:.*]], ^[[bb2:.*]] 87 br i1 %cond, label %call, label %nocall 88; CHECK: ^[[bb1]]: 89call: 90 ; CHECK: %[[invoke:.*]] = llvm.invoke @foo2() to ^[[bb3:.*]] unwind ^[[bb5:.*]] : () -> i32 91 %invoke = invoke i32 @foo2() to label %bb0 unwind label %bb1 92; CHECK: ^[[bb2]]: 93nocall: 94 ; CHECK: llvm.br ^[[bb4:.*]](%[[c0]], %[[c1]], %[[c2]] : i32, i32, i32) 95 br label %bb0 96; CHECK: ^[[bb3]]: 97 ; CHECK: llvm.br ^[[bb4]](%[[invoke]], %[[c20]], %[[invoke]] : i32, i32, i32) 98; CHECK: ^[[bb4]](%[[barg0:.*]]: i32, %[[barg1:.*]]: i32, %[[barg2:.*]]: i32): 99bb0: 100 %a = phi i32 [ 0, %nocall ], [ %invoke, %call ] 101 %b = phi i32 [ 1, %nocall ], [ 20, %call ] 102 %c = phi i32 [ 2, %nocall ], [ %invoke, %call ] 103 ; CHECK: %[[add0:.*]] = llvm.add %[[barg0]], %[[barg1]] : i32 104 ; CHECK: %[[add1:.*]] = llvm.add %[[barg2]], %[[add0]] : i32 105 %d = add i32 %a, %b 106 %e = add i32 %c, %d 107 ; CHECK: llvm.return %[[add1]] : i32 108 ret i32 %e 109; CHECK: ^[[bb5]]: 110bb1: 111 ; CHECK: %[[lp:.*]] = llvm.landingpad cleanup : i32 112 %resume = landingpad i32 cleanup 113 ; CHECK: llvm.resume %[[lp]] : i32 114 resume i32 %resume 115} 116 117declare void @f0(ptr) 118declare void @f1(i32) 119declare void @f2({ptr, i32}) 120 121; CHECK-LABEL: @landingpad_dominance 122define void @landingpad_dominance() personality ptr @__gxx_personality_v0 { 123entry: 124 ; CHECK: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr 125 ; CHECK: %[[c1:.*]] = llvm.mlir.constant(0 : i32) : i32 126 ; CHECK: %[[undef:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i32)> 127 ; CHECK: %[[tmpstruct:.*]] = llvm.insertvalue %[[null]], %[[undef]][0] : !llvm.struct<(ptr, i32)> 128 ; CHECK: %[[struct:.*]] = llvm.insertvalue %[[c1]], %[[tmpstruct]][1] : !llvm.struct<(ptr, i32)> 129 ; CHECK: llvm.call @f0(%[[null]]) : (!llvm.ptr) -> () 130 call void @f0(ptr null) 131 ; CHECK: llvm.call @f1(%[[c1]]) : (i32) -> () 132 call void @f1(i32 0) 133 ; CHECK: llvm.invoke @f0(%[[null]]) to ^[[block2:.*]] unwind ^[[block1:.*]] : (!llvm.ptr) -> () 134 invoke void @f0(ptr null) 135 to label %exit unwind label %catch 136 137; CHECK: ^[[block1]]: 138catch: 139 ; CHECK: %[[lp:.*]] = llvm.landingpad (catch %[[null]] : !llvm.ptr) : !llvm.struct<(ptr, i32)> 140 %lp = landingpad { ptr, i32 } catch ptr null 141 ; CHECK: llvm.call @f2(%[[struct]]) : (!llvm.struct<(ptr, i32)>) -> () 142 call void @f2({ptr, i32} {ptr null, i32 0}) 143 ; CHECK: llvm.resume %[[lp]] : !llvm.struct<(ptr, i32)> 144 resume {ptr, i32} %lp 145 146; CHECK: ^[[block2]]: 147exit: 148 ; CHECK: llvm.return 149 ret void 150} 151