1*cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*cee313d2SEric Christopher; RUN: opt -S -make-guards-explicit < %s | FileCheck %s 3*cee313d2SEric Christopher; RUN: opt -S -passes=make-guards-explicit < %s | FileCheck %s 4*cee313d2SEric Christopher 5*cee313d2SEric Christopherdeclare void @llvm.experimental.guard(i1,...) 6*cee313d2SEric Christopher 7*cee313d2SEric Christopher; Check that a sole guard can be turned into explicit guards form. 8*cee313d2SEric Christopherdefine void @trivial_guard(i1 %cond) { 9*cee313d2SEric Christopher; CHECK-LABEL: @trivial_guard( 10*cee313d2SEric Christopher; CHECK-NEXT: entry: 11*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 12*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND:%.*]], [[WIDENABLE_COND]] 13*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 14*cee313d2SEric Christopher; CHECK: deopt: 15*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] 16*cee313d2SEric Christopher; CHECK-NEXT: ret void 17*cee313d2SEric Christopher; CHECK: guarded: 18*cee313d2SEric Christopher; CHECK-NEXT: ret void 19*cee313d2SEric Christopher; 20*cee313d2SEric Christopherentry: 21*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"(i32 123, i64 456) ] 22*cee313d2SEric Christopher ret void 23*cee313d2SEric Christopher} 24*cee313d2SEric Christopher 25*cee313d2SEric Christopher; Check that a sequence of guards can be turned into explicit guards form. 26*cee313d2SEric Christopherdefine void @trivial_guard_sequence(i1 %cond1, i1 %cond2, i1 %cond3) { 27*cee313d2SEric Christopher; CHECK-LABEL: @trivial_guard_sequence( 28*cee313d2SEric Christopher; CHECK-NEXT: entry: 29*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 30*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] 31*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 32*cee313d2SEric Christopher; CHECK: deopt: 33*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] 34*cee313d2SEric Christopher; CHECK-NEXT: ret void 35*cee313d2SEric Christopher; CHECK: guarded: 36*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() 37*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] 38*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0 39*cee313d2SEric Christopher; CHECK: deopt2: 40*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] 41*cee313d2SEric Christopher; CHECK-NEXT: ret void 42*cee313d2SEric Christopher; CHECK: guarded1: 43*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() 44*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] 45*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0 46*cee313d2SEric Christopher; CHECK: deopt6: 47*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] 48*cee313d2SEric Christopher; CHECK-NEXT: ret void 49*cee313d2SEric Christopher; CHECK: guarded5: 50*cee313d2SEric Christopher; CHECK-NEXT: ret void 51*cee313d2SEric Christopher; 52*cee313d2SEric Christopherentry: 53*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"(i32 123, i64 456) ] 54*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond2) [ "deopt"(i32 789, i64 123) ] 55*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond3) [ "deopt"(i32 456, i64 789) ] 56*cee313d2SEric Christopher ret void 57*cee313d2SEric Christopher} 58*cee313d2SEric Christopher 59*cee313d2SEric Christopher; Check that all instructions between the guards preserve. 60*cee313d2SEric Christopherdefine void @split_block_contents(i1 %cond1, i1 %cond2, i1 %cond3, i32* %p) { 61*cee313d2SEric Christopher; CHECK-LABEL: @split_block_contents( 62*cee313d2SEric Christopher; CHECK-NEXT: entry: 63*cee313d2SEric Christopher; CHECK-NEXT: store i32 0, i32* [[P:%.*]] 64*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 65*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] 66*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 67*cee313d2SEric Christopher; CHECK: deopt: 68*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] 69*cee313d2SEric Christopher; CHECK-NEXT: ret void 70*cee313d2SEric Christopher; CHECK: guarded: 71*cee313d2SEric Christopher; CHECK-NEXT: store i32 1, i32* [[P]] 72*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() 73*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] 74*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0 75*cee313d2SEric Christopher; CHECK: deopt2: 76*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] 77*cee313d2SEric Christopher; CHECK-NEXT: ret void 78*cee313d2SEric Christopher; CHECK: guarded1: 79*cee313d2SEric Christopher; CHECK-NEXT: store i32 2, i32* [[P]] 80*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() 81*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] 82*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0 83*cee313d2SEric Christopher; CHECK: deopt6: 84*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] 85*cee313d2SEric Christopher; CHECK-NEXT: ret void 86*cee313d2SEric Christopher; CHECK: guarded5: 87*cee313d2SEric Christopher; CHECK-NEXT: store i32 3, i32* [[P]] 88*cee313d2SEric Christopher; CHECK-NEXT: ret void 89*cee313d2SEric Christopher; 90*cee313d2SEric Christopherentry: 91*cee313d2SEric Christopher store i32 0, i32* %p 92*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"(i32 123, i64 456) ] 93*cee313d2SEric Christopher store i32 1, i32* %p 94*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond2) [ "deopt"(i32 789, i64 123) ] 95*cee313d2SEric Christopher store i32 2, i32* %p 96*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %cond3) [ "deopt"(i32 456, i64 789) ] 97*cee313d2SEric Christopher store i32 3, i32* %p 98*cee313d2SEric Christopher ret void 99*cee313d2SEric Christopher} 100*cee313d2SEric Christopher 101*cee313d2SEric Christopher; Check that the guard can split a loop properly. 102*cee313d2SEric Christopherdefine void @split_loop(i1 %cond, i32 %N, i32 %M) { 103*cee313d2SEric Christopher; CHECK-LABEL: @split_loop( 104*cee313d2SEric Christopher; CHECK-NEXT: entry: 105*cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 106*cee313d2SEric Christopher; CHECK: loop: 107*cee313d2SEric Christopher; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ] 108*cee313d2SEric Christopher; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp slt i32 [[IV]], [[N:%.*]] 109*cee313d2SEric Christopher; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 110*cee313d2SEric Christopher; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]] 111*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0 112*cee313d2SEric Christopher; CHECK: deopt: 113*cee313d2SEric Christopher; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] 114*cee313d2SEric Christopher; CHECK-NEXT: ret void 115*cee313d2SEric Christopher; CHECK: guarded: 116*cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[M:%.*]] 117*cee313d2SEric Christopher; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 118*cee313d2SEric Christopher; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 119*cee313d2SEric Christopher; CHECK: exit: 120*cee313d2SEric Christopher; CHECK-NEXT: ret void 121*cee313d2SEric Christopher; 122*cee313d2SEric Christopherentry: 123*cee313d2SEric Christopher br label %loop 124*cee313d2SEric Christopher 125*cee313d2SEric Christopherloop: 126*cee313d2SEric Christopher %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 127*cee313d2SEric Christopher %guard_cond = icmp slt i32 %iv, %N 128*cee313d2SEric Christopher call void(i1, ...) @llvm.experimental.guard(i1 %guard_cond) [ "deopt"(i32 123, i64 456) ] 129*cee313d2SEric Christopher %loop_cond = icmp slt i32 %iv, %M 130*cee313d2SEric Christopher %iv.next = add i32 %iv, 1 131*cee313d2SEric Christopher br i1 %loop_cond, label %loop, label %exit 132*cee313d2SEric Christopher 133*cee313d2SEric Christopherexit: 134*cee313d2SEric Christopher ret void 135*cee313d2SEric Christopher} 136