1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -simplifycfg < %s | FileCheck %s 3 4declare void @llvm.experimental.guard(i1, ...) 5 6define 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; 12entry: 13 call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 14 ret i32 10 15} 16 17define 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 29entry: 30 br i1 %c, label %true, label %false 31 32true: 33 call void(i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ] 34 ret i32 10 35 36false: 37 ret i32 20 38} 39 40define 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; 50entry: 51 br i1 %c, label %guard_block, label %merge_block 52 53guard_block: 54 call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 55 %val = load i32, i32* %buf 56 br label %merge_block 57 58merge_block: 59 %to.return = phi i32 [ %val, %guard_block ], [ 50, %entry ] 60 ret i32 %to.return 61 62} 63 64define 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; 77entry: 78 %c0 = load volatile i1, i1* %c 79 br i1 %c0, label %guard_block, label %merge_block 80 81guard_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 87merge_block: 88 %c1 = load volatile i1, i1* %c 89 br i1 %c1, label %left, label %right 90 91left: 92 %val.left = phi i32 [ %val, %guard_block ], [ 50, %merge_block ] 93 ret i32 %val.left 94 95right: 96 %val.right = phi i32 [ %val, %guard_block ], [ 100, %merge_block ] 97 ret i32 %val.right 98 99 100} 101