brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.5 KiB · 355f70e Raw
530 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=guard-widening < %s        | FileCheck %s3; RUN: opt -S -passes=guard-widening < %s | FileCheck %s4 5declare void @llvm.experimental.guard(i1,...)6 7; Basic test case: we wide the first check to check both the8; conditions.9define void @f_0(i1 %cond_0, i1 %cond_1) {10; CHECK-LABEL: @f_0(11; CHECK-NEXT:  entry:12; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]13; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]14; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]15; CHECK-NEXT:    ret void16;17entry:18 19  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]20  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]21  ret void22}23 24; Same as @f_0, but with using a more general notion of postdominance.25define void @f_1(i1 %cond_0, i1 %cond_1, i1 %arg) {26; CHECK-LABEL: @f_1(27; CHECK-NEXT:  entry:28; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]29; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]30; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]31; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]32; CHECK:       left:33; CHECK-NEXT:    br label [[MERGE:%.*]]34; CHECK:       right:35; CHECK-NEXT:    br label [[MERGE]]36; CHECK:       merge:37; CHECK-NEXT:    ret void38;39entry:40 41  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]42  br i1 %arg, label %left, label %right43 44left:45  br label %merge46 47right:48  br label %merge49 50merge:51  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]52  ret void53}54 55; Like @f_1, but we have some code we need to hoist before we can56; widen a dominanting check.57define void @f_2(i32 %a, i32 %b, i1 %arg) {58; CHECK-LABEL: @f_2(59; CHECK-NEXT:  entry:60; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]61; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 1062; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 1063; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]64; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]65; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]66; CHECK:       left:67; CHECK-NEXT:    br label [[MERGE:%.*]]68; CHECK:       right:69; CHECK-NEXT:    br label [[MERGE]]70; CHECK:       merge:71; CHECK-NEXT:    ret void72;73entry:74 75  %cond_0 = icmp ult i32 %a, 1076  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]77  br i1 %arg, label %left, label %right78 79left:80  br label %merge81 82right:83  br label %merge84 85merge:86  %cond_1 = icmp ult i32 %b, 1087  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]88  ret void89}90 91; Negative test: don't hoist stuff out of control flow92; indiscriminately, since that can make us do more work than needed.93define void @f_3(i32 %a, i32 %b, i1 %arg) {94; CHECK-LABEL: @f_3(95; CHECK-NEXT:  entry:96; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 1097; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0]]) [ "deopt"() ]98; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]99; CHECK:       left:100; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10101; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1]]) [ "deopt"() ]102; CHECK-NEXT:    ret void103; CHECK:       right:104; CHECK-NEXT:    ret void105;106entry:107 108  %cond_0 = icmp ult i32 %a, 10109  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]110  br i1 %arg, label %left, label %right111 112left:113 114  %cond_1 = icmp ult i32 %b, 10115  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]116  ret void117 118right:119  ret void120}121 122; But hoisting out of control flow is fine if it makes a loop computed123; condition loop invariant.  This behavior may require some tuning in124; the future.125define void @f_4(i32 %a, i32 %b, i1 %arg) {126; CHECK-LABEL: @f_4(127; CHECK-NEXT:  entry:128; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]129; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10130; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10131; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]132; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]133; CHECK-NEXT:    br i1 %arg, label [[LOOP:%.*]], label [[LEAVE:%.*]]134; CHECK:       loop:135; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[LEAVE]]136; CHECK:       leave:137; CHECK-NEXT:    ret void138;139entry:140 141  %cond_0 = icmp ult i32 %a, 10142  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]143  br i1 %arg, label %loop, label %leave144 145loop:146  %cond_1 = icmp ult i32 %b, 10147  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]148  br i1 %arg, label %loop, label %leave149 150leave:151  ret void152}153 154; Hoisting out of control flow is also fine if we can widen the155; dominating check without doing any extra work.156define void @f_5(i32 %a, i1 %arg) {157; CHECK-LABEL: @f_5(158; CHECK-NEXT:  entry:159; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7160; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11161; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]162; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]163; CHECK:       left:164; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[A]], 10165; CHECK-NEXT:    ret void166; CHECK:       right:167; CHECK-NEXT:    ret void168;169entry:170 171  %cond_0 = icmp ugt i32 %a, 7172  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]173  br i1 %arg, label %left, label %right174 175left:176  %cond_1 = icmp ugt i32 %a, 10177  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]178  ret void179 180right:181  ret void182}183 184; Negative test: the load from %a can be safely speculated to before185; the first guard, but there is no guarantee that it will produce the186; same value.187define void @f_6(ptr dereferenceable(32) %a, ptr %b, i1 %unknown) {188; CHECK-LABEL: @f_6(189; CHECK-NEXT:  entry:190; CHECK-NEXT:    [[COND_0:%.*]] = load i1, ptr [[A:%.*]], align 1191; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0]]) [ "deopt"() ]192; CHECK-NEXT:    store i1 [[UNKNOWN:%.*]], ptr [[B:%.*]], align 1193; CHECK-NEXT:    [[COND_1:%.*]] = load i1, ptr [[A]], align 1194; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1]]) [ "deopt"() ]195; CHECK-NEXT:    ret void196;197entry:198  %cond_0 = load i1, ptr %a199  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]200  store i1 %unknown, ptr %b201  %cond_1 = load i1, ptr %a202  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]203  ret void204}205 206; All else equal, we try to widen the earliest guard we can.  This207; heuristic can use some tuning.208define void @f_7(i32 %a, ptr %cond_buf, i1 %arg) {209; CHECK-LABEL: @f_7(210; CHECK-NEXT:  entry:211; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]212; CHECK-NEXT:    [[COND_1:%.*]] = load volatile i1, ptr [[COND_BUF:%.*]], align 1213; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7214; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]215; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]216; CHECK-NEXT:    [[COND_2:%.*]] = load volatile i1, ptr [[COND_BUF]], align 1217; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2]]) [ "deopt"() ]218; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]219; CHECK:       left:220; CHECK-NEXT:    br label [[LEFT]]221; CHECK:       right:222; CHECK-NEXT:    ret void223;224entry:225 226  %cond_1 = load volatile i1, ptr %cond_buf227  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]228  %cond_2 = load volatile i1, ptr %cond_buf229  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ]230  br i1 %arg, label %left, label %right231 232left:233  %cond_3 = icmp ult i32 %a, 7234  call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ]235  br label %left236 237right:238  ret void239}240 241; In this case the earliest dominating guard is in a loop, and we242; don't want to put extra work in there.  This heuristic can use some243; tuning.244define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2, i1 %arg) {245; CHECK-LABEL: @f_8(246; CHECK-NEXT:  entry:247; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]248; CHECK-NEXT:    br label [[LOOP:%.*]]249; CHECK:       loop:250; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1:%.*]]) [ "deopt"() ]251; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[LEAVE:%.*]]252; CHECK:       leave:253; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7254; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]]255; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]256; CHECK-NEXT:    br i1 %arg, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]257; CHECK:       loop2:258; CHECK-NEXT:    br label [[LOOP2]]259; CHECK:       leave2:260; CHECK-NEXT:    ret void261;262entry:263  br label %loop264 265loop:266  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]267  br i1 %arg, label %loop, label %leave268 269leave:270 271  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ]272  br i1 %arg, label %loop2, label %leave2273 274loop2:275  %cond_3 = icmp ult i32 %a, 7276  call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ]277  br label %loop2278 279leave2:280  ret void281}282 283; In cases like these where there isn't any "obviously profitable"284; widening sites, we refuse to do anything.285define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {286; CHECK-LABEL: @f_9(287; CHECK-NEXT:  entry:288; CHECK-NEXT:    br label [[FIRST_LOOP:%.*]]289; CHECK:       first_loop:290; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]291; CHECK-NEXT:    br i1 %arg, label [[FIRST_LOOP]], label [[SECOND_LOOP:%.*]]292; CHECK:       second_loop:293; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1:%.*]]) [ "deopt"() ]294; CHECK-NEXT:    br label [[SECOND_LOOP]]295;296entry:297  br label %first_loop298 299first_loop:300 301  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]302  br i1 %arg, label %first_loop, label %second_loop303 304second_loop:305 306  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]307  br label %second_loop308}309 310; Same situation as in @f_9: no "obviously profitable" widening sites,311; so we refuse to do anything.312define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {313; CHECK-LABEL: @f_10(314; CHECK-NEXT:  entry:315; CHECK-NEXT:    br label [[LOOP:%.*]]316; CHECK:       loop:317; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]318; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[NO_LOOP:%.*]]319; CHECK:       no_loop:320; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1:%.*]]) [ "deopt"() ]321; CHECK-NEXT:    ret void322;323entry:324  br label %loop325 326loop:327 328  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]329  br i1 %arg, label %loop, label %no_loop330 331no_loop:332  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]333  ret void334}335 336; With guards in loops, we're okay hoisting out the guard into the337; containing loop.338define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {339; CHECK-LABEL: @f_11(340; CHECK-NEXT:  entry:341; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]342; CHECK-NEXT:    br label [[INNER:%.*]]343; CHECK:       inner:344; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]345; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]346; CHECK-NEXT:    br i1 %arg, label [[INNER]], label [[OUTER:%.*]]347; CHECK:       outer:348; CHECK-NEXT:    br label [[INNER]]349;350entry:351  br label %inner352 353inner:354 355  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]356  br i1 %arg, label %inner, label %outer357 358outer:359  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]360  br label %inner361}362 363; Checks that we are adequately guarded against exponential-time364; behavior when hoisting code.365define void @f_12(i32 %a0) {366; CHECK-LABEL: @f_12(367; CHECK-NEXT:  entry:368; CHECK-NEXT:    [[A0_GW_FR:%.*]] = freeze i32 [[A0:%.*]]369; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A0_GW_FR]], [[A0_GW_FR]]370; CHECK-NEXT:    [[A2:%.*]] = mul i32 [[A1]], [[A1]]371; CHECK-NEXT:    [[A3:%.*]] = mul i32 [[A2]], [[A2]]372; CHECK-NEXT:    [[A4:%.*]] = mul i32 [[A3]], [[A3]]373; CHECK-NEXT:    [[A5:%.*]] = mul i32 [[A4]], [[A4]]374; CHECK-NEXT:    [[A6:%.*]] = mul i32 [[A5]], [[A5]]375; CHECK-NEXT:    [[A7:%.*]] = mul i32 [[A6]], [[A6]]376; CHECK-NEXT:    [[A8:%.*]] = mul i32 [[A7]], [[A7]]377; CHECK-NEXT:    [[A9:%.*]] = mul i32 [[A8]], [[A8]]378; CHECK-NEXT:    [[A10:%.*]] = mul i32 [[A9]], [[A9]]379; CHECK-NEXT:    [[A11:%.*]] = mul i32 [[A10]], [[A10]]380; CHECK-NEXT:    [[A12:%.*]] = mul i32 [[A11]], [[A11]]381; CHECK-NEXT:    [[A13:%.*]] = mul i32 [[A12]], [[A12]]382; CHECK-NEXT:    [[A14:%.*]] = mul i32 [[A13]], [[A13]]383; CHECK-NEXT:    [[A15:%.*]] = mul i32 [[A14]], [[A14]]384; CHECK-NEXT:    [[A16:%.*]] = mul i32 [[A15]], [[A15]]385; CHECK-NEXT:    [[A17:%.*]] = mul i32 [[A16]], [[A16]]386; CHECK-NEXT:    [[A18:%.*]] = mul i32 [[A17]], [[A17]]387; CHECK-NEXT:    [[A19:%.*]] = mul i32 [[A18]], [[A18]]388; CHECK-NEXT:    [[A20:%.*]] = mul i32 [[A19]], [[A19]]389; CHECK-NEXT:    [[A21:%.*]] = mul i32 [[A20]], [[A20]]390; CHECK-NEXT:    [[A22:%.*]] = mul i32 [[A21]], [[A21]]391; CHECK-NEXT:    [[A23:%.*]] = mul i32 [[A22]], [[A22]]392; CHECK-NEXT:    [[A24:%.*]] = mul i32 [[A23]], [[A23]]393; CHECK-NEXT:    [[A25:%.*]] = mul i32 [[A24]], [[A24]]394; CHECK-NEXT:    [[A26:%.*]] = mul i32 [[A25]], [[A25]]395; CHECK-NEXT:    [[A27:%.*]] = mul i32 [[A26]], [[A26]]396; CHECK-NEXT:    [[A28:%.*]] = mul i32 [[A27]], [[A27]]397; CHECK-NEXT:    [[A29:%.*]] = mul i32 [[A28]], [[A28]]398; CHECK-NEXT:    [[A30:%.*]] = mul i32 [[A29]], [[A29]]399; CHECK-NEXT:    [[COND:%.*]] = trunc i32 [[A30]] to i1400; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND]]401; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]402; CHECK-NEXT:    ret void403;404 405; Eliding the earlier 29 multiplications for brevity406 407entry:408  call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]409  %a1 = mul i32 %a0, %a0410  %a2 = mul i32 %a1, %a1411  %a3 = mul i32 %a2, %a2412  %a4 = mul i32 %a3, %a3413  %a5 = mul i32 %a4, %a4414  %a6 = mul i32 %a5, %a5415  %a7 = mul i32 %a6, %a6416  %a8 = mul i32 %a7, %a7417  %a9 = mul i32 %a8, %a8418  %a10 = mul i32 %a9, %a9419  %a11 = mul i32 %a10, %a10420  %a12 = mul i32 %a11, %a11421  %a13 = mul i32 %a12, %a12422  %a14 = mul i32 %a13, %a13423  %a15 = mul i32 %a14, %a14424  %a16 = mul i32 %a15, %a15425  %a17 = mul i32 %a16, %a16426  %a18 = mul i32 %a17, %a17427  %a19 = mul i32 %a18, %a18428  %a20 = mul i32 %a19, %a19429  %a21 = mul i32 %a20, %a20430  %a22 = mul i32 %a21, %a21431  %a23 = mul i32 %a22, %a22432  %a24 = mul i32 %a23, %a23433  %a25 = mul i32 %a24, %a24434  %a26 = mul i32 %a25, %a25435  %a27 = mul i32 %a26, %a26436  %a28 = mul i32 %a27, %a27437  %a29 = mul i32 %a28, %a28438  %a30 = mul i32 %a29, %a29439  %cond = trunc i32 %a30 to i1440  call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]441  ret void442}443 444define void @f_13(i32 %a, i1 %arg) {445; CHECK-LABEL: @f_13(446; CHECK-NEXT:  entry:447; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14448; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10449; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]450; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]451; CHECK:       left:452; CHECK-NEXT:    [[COND_1:%.*]] = icmp slt i32 [[A]], 10453; CHECK-NEXT:    ret void454; CHECK:       right:455; CHECK-NEXT:    ret void456;457entry:458 459  %cond_0 = icmp ult i32 %a, 14460  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]461  br i1 %arg, label %left, label %right462 463left:464  %cond_1 = icmp slt i32 %a, 10465  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]466  ret void467 468right:469  ret void470}471 472define void @f_14(i32 %a, i1 %arg) {473; CHECK-LABEL: @f_14(474; CHECK-NEXT:  entry:475; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14476; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0]]) [ "deopt"() ]477; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]478; CHECK:       left:479; CHECK-NEXT:    [[COND_1:%.*]] = icmp sgt i32 [[A]], 10480; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_1]]) [ "deopt"() ]481; CHECK-NEXT:    ret void482; CHECK:       right:483; CHECK-NEXT:    ret void484;485entry:486 487  %cond_0 = icmp ult i32 %a, 14488  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]489  br i1 %arg, label %left, label %right490 491left:492 493  %cond_1 = icmp sgt i32 %a, 10494  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]495  ret void496 497right:498  ret void499}500 501; Make sure we do not widen guard by trivial true conditions into something.502define void @f_15(i1 %cond_0, i1 %cond_1) {503; CHECK-LABEL: @f_15(504; CHECK-NEXT:  entry:505; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]506; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]507; CHECK-NEXT:    ret void508;509entry:510 511  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]512  call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]513  ret void514}515 516; Make sure we do not widen guard by trivial false conditions into something.517define void @f_16(i1 %cond_0, i1 %cond_1) {518; CHECK-LABEL: @f_16(519; CHECK-NEXT:  entry:520; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]521; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]522; CHECK-NEXT:    ret void523;524entry:525 526  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]527  call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]528  ret void529}530