1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt -S -simplifycfg < %s | FileCheck %s 3 4 declare void @llvm.experimental.guard(i1, ...) 5 6 define i32 @f_0(i1 %c) { 7 ; CHECK-LABEL: @f_0( 8 ; CHECK-NEXT: entry: 9 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 10 ; CHECK-NEXT: unreachable 11 ; 12 entry: 13 call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 14 ret i32 10 15 } 16 17 define i32 @f_1(i1 %c) { 18 ; Demonstrate that we (intentionally) do not simplify a guard on undef 19 ; CHECK-LABEL: @f_1( 20 ; CHECK-NEXT: entry: 21 ; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 22 ; CHECK: true: 23 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ] 24 ; CHECK-NEXT: ret i32 10 25 ; CHECK: false: 26 ; CHECK-NEXT: ret i32 20 27 ; 28 29 entry: 30 br i1 %c, label %true, label %false 31 32 true: 33 call void(i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ] 34 ret i32 10 35 36 false: 37 ret i32 20 38 } 39 40 define i32 @f_2(i1 %c, i32* %buf) { 41 ; CHECK-LABEL: @f_2( 42 ; CHECK-NEXT: entry: 43 ; CHECK-NEXT: br i1 [[C:%.*]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]] 44 ; CHECK: guard_block: 45 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 46 ; CHECK-NEXT: unreachable 47 ; CHECK: merge_block: 48 ; CHECK-NEXT: ret i32 50 49 ; 50 entry: 51 br i1 %c, label %guard_block, label %merge_block 52 53 guard_block: 54 call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 55 %val = load i32, i32* %buf 56 br label %merge_block 57 58 merge_block: 59 %to.return = phi i32 [ %val, %guard_block ], [ 50, %entry ] 60 ret i32 %to.return 61 62 } 63 64 define i32 @f_3(i1* %c, i32* %buf) { 65 ; CHECK-LABEL: @f_3( 66 ; CHECK-NEXT: entry: 67 ; CHECK-NEXT: [[C0:%.*]] = load volatile i1, i1* [[C:%.*]] 68 ; CHECK-NEXT: br i1 [[C0]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]] 69 ; CHECK: guard_block: 70 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 71 ; CHECK-NEXT: unreachable 72 ; CHECK: merge_block: 73 ; CHECK-NEXT: [[C1:%.*]] = load volatile i1, i1* [[C]] 74 ; CHECK-NEXT: [[DOT:%.*]] = select i1 [[C1]], i32 50, i32 100 75 ; CHECK-NEXT: ret i32 [[DOT]] 76 ; 77 entry: 78 %c0 = load volatile i1, i1* %c 79 br i1 %c0, label %guard_block, label %merge_block 80 81 guard_block: 82 call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 83 %val = load i32, i32* %buf 84 %c2 = load volatile i1, i1* %c 85 br i1 %c2, label %left, label %right 86 87 merge_block: 88 %c1 = load volatile i1, i1* %c 89 br i1 %c1, label %left, label %right 90 91 left: 92 %val.left = phi i32 [ %val, %guard_block ], [ 50, %merge_block ] 93 ret i32 %val.left 94 95 right: 96 %val.right = phi i32 [ %val, %guard_block ], [ 100, %merge_block ] 97 ret i32 %val.right 98 99 100 } 101