brintos

brintos / llvm-project-archived public Read only

0
0
Text · 49.2 KiB · 310c4a8 Raw
1127 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -guard-widening-widen-branch-guards=true -passes=guard-widening < %s        | FileCheck %s3; RUN: opt -S -guard-widening-widen-branch-guards=true -passes=guard-widening < %s | FileCheck %s4 5; Basic test case: we wide the first check to check both the6; conditions.7define void @f_0(i1 %cond_0, i1 %cond_1) {8; CHECK-LABEL: @f_0(9; CHECK-NEXT:  entry:10; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]11; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]12; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()13; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]14; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]15; CHECK:       deopt:16; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]17; CHECK-NEXT:    ret void18; CHECK:       guarded:19; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()20; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]21; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]22; CHECK:       deopt2:23; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]24; CHECK-NEXT:    ret void25; CHECK:       guarded1:26; CHECK-NEXT:    ret void27;28entry:29  %widenable_cond = call i1 @llvm.experimental.widenable.condition()30  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond31  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !032 33deopt:                                            ; preds = %entry34  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]35  ret void36 37guarded:                                          ; preds = %entry38  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()39  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond340  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !041 42deopt2:                                           ; preds = %guarded43  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]44  ret void45 46guarded1:                                         ; preds = %guarded47  ret void48}49 50; Same as @f_0, but with using a more general notion of postdominance.51define void @f_1(i1 %cond_0, i1 %cond_1, i1 %arg) {52; CHECK-LABEL: @f_1(53; CHECK-NEXT:  entry:54; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]55; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]56; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()57; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]58; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]59; CHECK:       deopt:60; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]61; CHECK-NEXT:    ret void62; CHECK:       guarded:63; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]64; CHECK:       left:65; CHECK-NEXT:    br label [[MERGE:%.*]]66; CHECK:       right:67; CHECK-NEXT:    br label [[MERGE]]68; CHECK:       merge:69; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()70; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]71; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]72; CHECK:       deopt2:73; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]74; CHECK-NEXT:    ret void75; CHECK:       guarded1:76; CHECK-NEXT:    ret void77;78entry:79  %widenable_cond = call i1 @llvm.experimental.widenable.condition()80  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond81  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !082 83deopt:                                            ; preds = %entry84  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]85  ret void86 87guarded:                                          ; preds = %entry88  br i1 %arg, label %left, label %right89 90left:                                             ; preds = %guarded91  br label %merge92 93right:                                            ; preds = %guarded94  br label %merge95 96merge:                                            ; preds = %right, %left97  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()98  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond399  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0100 101deopt2:                                           ; preds = %merge102  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]103  ret void104 105guarded1:                                         ; preds = %merge106  ret void107}108 109; Like @f_1, but we have some code we need to hoist before we can110; widen a dominanting check.111define void @f_2(i32 %a, i32 %b, i1 %arg) {112; CHECK-LABEL: @f_2(113; CHECK-NEXT:  entry:114; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]115; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10116; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10117; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]118; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()119; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]120; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]121; CHECK:       deopt:122; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]123; CHECK-NEXT:    ret void124; CHECK:       guarded:125; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]126; CHECK:       left:127; CHECK-NEXT:    br label [[MERGE:%.*]]128; CHECK:       right:129; CHECK-NEXT:    br label [[MERGE]]130; CHECK:       merge:131; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()132; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]133; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]134; CHECK:       deopt2:135; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]136; CHECK-NEXT:    ret void137; CHECK:       guarded1:138; CHECK-NEXT:    ret void139;140entry:141  %cond_0 = icmp ult i32 %a, 10142  %widenable_cond = call i1 @llvm.experimental.widenable.condition()143  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond144  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0145 146deopt:                                            ; preds = %entry147  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]148  ret void149 150guarded:                                          ; preds = %entry151  br i1 %arg, label %left, label %right152 153left:                                             ; preds = %guarded154  br label %merge155 156right:                                            ; preds = %guarded157  br label %merge158 159merge:                                            ; preds = %right, %left160  %cond_1 = icmp ult i32 %b, 10161  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()162  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3163  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0164 165deopt2:                                           ; preds = %merge166  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]167  ret void168 169guarded1:                                         ; preds = %merge170  ret void171}172 173; Negative test: don't hoist stuff out of control flow174; indiscriminately, since that can make us do more work than needed.175define void @f_3(i32 %a, i32 %b, i1 %arg) {176; CHECK-LABEL: @f_3(177; CHECK-NEXT:  entry:178; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10179; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()180; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]181; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]182; CHECK:       deopt:183; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]184; CHECK-NEXT:    ret void185; CHECK:       guarded:186; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]187; CHECK:       left:188; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10189; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()190; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]191; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]192; CHECK:       deopt2:193; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]194; CHECK-NEXT:    ret void195; CHECK:       guarded1:196; CHECK-NEXT:    ret void197; CHECK:       right:198; CHECK-NEXT:    ret void199;200entry:201  %cond_0 = icmp ult i32 %a, 10202  %widenable_cond = call i1 @llvm.experimental.widenable.condition()203  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond204  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0205 206deopt:                                            ; preds = %entry207  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]208  ret void209 210guarded:                                          ; preds = %entry211  br i1 %arg, label %left, label %right212 213left:                                             ; preds = %guarded214  %cond_1 = icmp ult i32 %b, 10215  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()216  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3217  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0218 219deopt2:                                           ; preds = %left220  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]221  ret void222 223guarded1:                                         ; preds = %left224  ret void225 226right:                                            ; preds = %guarded227  ret void228}229 230; But hoisting out of control flow is fine if it makes a loop computed231; condition loop invariant.  This behavior may require some tuning in232; the future.233define void @f_4(i32 %a, i32 %b, i1 %arg) {234; CHECK-LABEL: @f_4(235; CHECK-NEXT:  entry:236; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]237; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10238; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10239; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]240; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()241; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]242; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]243; CHECK:       deopt:244; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]245; CHECK-NEXT:    ret void246; CHECK:       guarded:247; CHECK-NEXT:    br i1 %arg, label [[LOOP:%.*]], label [[LEAVE:%.*]]248; CHECK:       loop:249; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()250; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]251; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]252; CHECK:       deopt2:253; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]254; CHECK-NEXT:    ret void255; CHECK:       guarded1:256; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[LEAVE]]257; CHECK:       leave:258; CHECK-NEXT:    ret void259;260entry:261  %cond_0 = icmp ult i32 %a, 10262  %widenable_cond = call i1 @llvm.experimental.widenable.condition()263  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond264  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0265 266deopt:                                            ; preds = %entry267  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]268  ret void269 270guarded:                                          ; preds = %entry271  br i1 %arg, label %loop, label %leave272 273loop:                                             ; preds = %guarded1, %guarded274  %cond_1 = icmp ult i32 %b, 10275  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()276  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3277  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0278 279deopt2:                                           ; preds = %loop280  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]281  ret void282 283guarded1:                                         ; preds = %loop284  br i1 %arg, label %loop, label %leave285 286leave:                                            ; preds = %guarded1, %guarded287  ret void288}289 290; Hoisting out of control flow is also fine if we can widen the291; dominating check without doing any extra work.292define void @f_5(i32 %a, i1 %arg) {293; CHECK-LABEL: @f_5(294; CHECK-NEXT:  entry:295; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7296; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11297; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()298; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]299; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]300; CHECK:       deopt:301; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]302; CHECK-NEXT:    ret void303; CHECK:       guarded:304; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]305; CHECK:       left:306; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[A]], 10307; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()308; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]309; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]310; CHECK:       deopt2:311; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]312; CHECK-NEXT:    ret void313; CHECK:       guarded1:314; CHECK-NEXT:    ret void315; CHECK:       right:316; CHECK-NEXT:    ret void317;318entry:319  %cond_0 = icmp ugt i32 %a, 7320  %widenable_cond = call i1 @llvm.experimental.widenable.condition()321  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond322  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0323 324deopt:                                            ; preds = %entry325  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]326  ret void327 328guarded:                                          ; preds = %entry329  br i1 %arg, label %left, label %right330 331left:                                             ; preds = %guarded332  %cond_1 = icmp ugt i32 %a, 10333  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()334  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3335  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0336 337deopt2:                                           ; preds = %left338  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]339  ret void340 341guarded1:                                         ; preds = %left342  ret void343 344right:                                            ; preds = %guarded345  ret void346}347 348; Negative test: the load from %a can be safely speculated to before349; the first guard, but there is no guarantee that it will produce the350; same value.351define void @f_6(ptr dereferenceable(32) %a, ptr %b, i1 %unknown) {352; CHECK-LABEL: @f_6(353; CHECK-NEXT:  entry:354; CHECK-NEXT:    [[COND_0:%.*]] = load i1, ptr [[A:%.*]], align 1355; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()356; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]357; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]358; CHECK:       deopt:359; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]360; CHECK-NEXT:    ret void361; CHECK:       guarded:362; CHECK-NEXT:    store i1 [[UNKNOWN:%.*]], ptr [[B:%.*]], align 1363; CHECK-NEXT:    [[COND_1:%.*]] = load i1, ptr [[A]], align 1364; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()365; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]366; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]367; CHECK:       deopt2:368; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]369; CHECK-NEXT:    ret void370; CHECK:       guarded1:371; CHECK-NEXT:    ret void372;373entry:374  %cond_0 = load i1, ptr %a375  %widenable_cond = call i1 @llvm.experimental.widenable.condition()376  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond377  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0378 379deopt:                                            ; preds = %entry380  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]381  ret void382 383guarded:                                          ; preds = %entry384  store i1 %unknown, ptr %b385  %cond_1 = load i1, ptr %a386  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()387  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3388  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0389 390deopt2:                                           ; preds = %guarded391  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]392  ret void393 394guarded1:                                         ; preds = %guarded395  ret void396}397 398; All else equal, we try to widen the earliest guard we can.  This399; heuristic can use some tuning.400define void @f_7(i32 %a, ptr %cond_buf, i1 %arg) {401; CHECK-LABEL: @f_7(402; CHECK-NEXT:  entry:403; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]404; CHECK-NEXT:    [[COND_1:%.*]] = load volatile i1, ptr [[COND_BUF:%.*]], align 1405; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7406; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]407; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()408; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]409; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]410; CHECK:       deopt:411; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]412; CHECK-NEXT:    ret void413; CHECK:       guarded:414; CHECK-NEXT:    [[COND_2:%.*]] = load volatile i1, ptr [[COND_BUF]], align 1415; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()416; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2]], [[WIDENABLE_COND3]]417; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]418; CHECK:       deopt2:419; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]420; CHECK-NEXT:    ret void421; CHECK:       guarded1:422; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]423; CHECK:       left:424; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()425; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]426; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof [[PROF0]]427; CHECK:       deopt6:428; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]429; CHECK-NEXT:    ret void430; CHECK:       guarded5:431; CHECK-NEXT:    br label [[LEFT]]432; CHECK:       right:433; CHECK-NEXT:    ret void434;435entry:436  %cond_1 = load volatile i1, ptr %cond_buf437  %widenable_cond = call i1 @llvm.experimental.widenable.condition()438  %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond439  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0440 441deopt:                                            ; preds = %entry442  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]443  ret void444 445guarded:                                          ; preds = %entry446  %cond_2 = load volatile i1, ptr %cond_buf447  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()448  %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3449  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0450 451deopt2:                                           ; preds = %guarded452  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]453  ret void454 455guarded1:                                         ; preds = %guarded456  br i1 %arg, label %left, label %right457 458left:                                             ; preds = %guarded5, %guarded1459  %cond_3 = icmp ult i32 %a, 7460  %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()461  %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7462  br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0463 464deopt6:                                           ; preds = %left465  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]466  ret void467 468guarded5:                                         ; preds = %left469  br label %left470 471right:                                            ; preds = %guarded1472  ret void473}474 475; In this case the earliest dominating guard is in a loop, and we476; don't want to put extra work in there.  This heuristic can use some477; tuning.478define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2, i1 %arg) {479; CHECK-LABEL: @f_8(480; CHECK-NEXT:  entry:481; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]482; CHECK-NEXT:    br label [[LOOP:%.*]]483; CHECK:       loop:484; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()485; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND]]486; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]487; CHECK:       deopt:488; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]489; CHECK-NEXT:    ret void490; CHECK:       guarded:491; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[LEAVE:%.*]]492; CHECK:       leave:493; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7494; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]]495; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()496; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]]497; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]498; CHECK:       deopt2:499; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]500; CHECK-NEXT:    ret void501; CHECK:       guarded1:502; CHECK-NEXT:    br i1 %arg, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]503; CHECK:       loop2:504; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()505; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]506; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof [[PROF0]]507; CHECK:       deopt6:508; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]509; CHECK-NEXT:    ret void510; CHECK:       guarded5:511; CHECK-NEXT:    br label [[LOOP2]]512; CHECK:       leave2:513; CHECK-NEXT:    ret void514;515entry:516  br label %loop517 518loop:                                             ; preds = %guarded, %entry519  %widenable_cond = call i1 @llvm.experimental.widenable.condition()520  %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond521  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0522 523deopt:                                            ; preds = %loop524  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]525  ret void526 527guarded:                                          ; preds = %loop528  br i1 %arg, label %loop, label %leave529 530leave:                                            ; preds = %guarded531  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()532  %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3533  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0534 535deopt2:                                           ; preds = %leave536  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]537  ret void538 539guarded1:                                         ; preds = %leave540  br i1 %arg, label %loop2, label %leave2541 542loop2:                                            ; preds = %guarded5, %guarded1543  %cond_3 = icmp ult i32 %a, 7544  %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()545  %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7546  br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0547 548deopt6:                                           ; preds = %loop2549  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]550  ret void551 552guarded5:                                         ; preds = %loop2553  br label %loop2554 555leave2:                                           ; preds = %guarded1556  ret void557}558 559; In cases like these where there isn't any "obviously profitable"560; widening sites, we refuse to do anything.561define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {562; CHECK-LABEL: @f_9(563; CHECK-NEXT:  entry:564; CHECK-NEXT:    br label [[FIRST_LOOP:%.*]]565; CHECK:       first_loop:566; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()567; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]568; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]569; CHECK:       deopt:570; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]571; CHECK-NEXT:    ret void572; CHECK:       guarded:573; CHECK-NEXT:    br i1 %arg, label [[FIRST_LOOP]], label [[SECOND_LOOP:%.*]]574; CHECK:       second_loop:575; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()576; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]577; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]578; CHECK:       deopt2:579; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]580; CHECK-NEXT:    ret void581; CHECK:       guarded1:582; CHECK-NEXT:    br label [[SECOND_LOOP]]583;584entry:585  br label %first_loop586 587first_loop:                                       ; preds = %guarded, %entry588  %widenable_cond = call i1 @llvm.experimental.widenable.condition()589  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond590  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0591 592deopt:                                            ; preds = %first_loop593  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]594  ret void595 596guarded:                                          ; preds = %first_loop597  br i1 %arg, label %first_loop, label %second_loop598 599second_loop:                                      ; preds = %guarded1, %guarded600  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()601  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3602  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0603 604deopt2:                                           ; preds = %second_loop605  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]606  ret void607 608guarded1:                                         ; preds = %second_loop609  br label %second_loop610}611 612; Same situation as in @f_9: no "obviously profitable" widening sites,613; so we refuse to do anything.614define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {615; CHECK-LABEL: @f_10(616; CHECK-NEXT:  entry:617; CHECK-NEXT:    br label [[LOOP:%.*]]618; CHECK:       loop:619; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()620; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]621; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]622; CHECK:       deopt:623; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]624; CHECK-NEXT:    ret void625; CHECK:       guarded:626; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[NO_LOOP:%.*]]627; CHECK:       no_loop:628; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()629; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]630; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]631; CHECK:       deopt2:632; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]633; CHECK-NEXT:    ret void634; CHECK:       guarded1:635; CHECK-NEXT:    ret void636;637entry:638  br label %loop639 640loop:                                             ; preds = %guarded, %entry641  %widenable_cond = call i1 @llvm.experimental.widenable.condition()642  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond643  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0644 645deopt:                                            ; preds = %loop646  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]647  ret void648 649guarded:                                          ; preds = %loop650  br i1 %arg, label %loop, label %no_loop651 652no_loop:                                          ; preds = %guarded653  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()654  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3655  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0656 657deopt2:                                           ; preds = %no_loop658  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]659  ret void660 661guarded1:                                         ; preds = %no_loop662  ret void663}664 665; With guards in loops, we're okay hoisting out the guard into the666; containing loop.667define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {668; CHECK-LABEL: @f_11(669; CHECK-NEXT:  entry:670; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]671; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]672; CHECK:       outer_header:673; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]674; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()675; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]676; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]677; CHECK:       deopt:678; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]679; CHECK-NEXT:    ret void680; CHECK:       guarded:681; CHECK-NEXT:    br label [[INNER:%.*]]682; CHECK:       inner:683; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()684; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]685; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]686; CHECK:       deopt2:687; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]688; CHECK-NEXT:    ret void689; CHECK:       guarded1:690; CHECK-NEXT:    br i1 %arg, label [[INNER]], label [[OUTER_LATCH:%.*]]691; CHECK:       outer_latch:692; CHECK-NEXT:    br i1 %arg, label [[OUTER_HEADER]], label [[EXIT:%.*]]693; CHECK:       exit:694; CHECK-NEXT:    ret void695;696entry:697  br label %outer_header698 699outer_header:                                     ; preds = %outer_latch, %entry700  %widenable_cond = call i1 @llvm.experimental.widenable.condition()701  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond702  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0703 704deopt:                                            ; preds = %outer_header705  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]706  ret void707 708guarded:                                          ; preds = %outer_header709  br label %inner710 711inner:                                            ; preds = %guarded1, %guarded712  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()713  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3714  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0715 716deopt2:                                           ; preds = %inner717  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]718  ret void719 720guarded1:                                         ; preds = %inner721  br i1 %arg, label %inner, label %outer_latch722 723outer_latch:                                      ; preds = %guarded1724  br i1 %arg, label %outer_header, label %exit725 726exit:                                             ; preds = %outer_latch727  ret void728}729 730; Checks that we are adequately guarded against exponential-time731; behavior when hoisting code.732define void @f_12(i32 %a0) {733; CHECK-LABEL: @f_12(734; CHECK-NEXT:  entry:735; CHECK-NEXT:    [[A0_GW_FR:%.*]] = freeze i32 [[A0:%.*]]736; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A0_GW_FR]], [[A0_GW_FR]]737; CHECK-NEXT:    [[A2:%.*]] = mul i32 [[A1]], [[A1]]738; CHECK-NEXT:    [[A3:%.*]] = mul i32 [[A2]], [[A2]]739; CHECK-NEXT:    [[A4:%.*]] = mul i32 [[A3]], [[A3]]740; CHECK-NEXT:    [[A5:%.*]] = mul i32 [[A4]], [[A4]]741; CHECK-NEXT:    [[A6:%.*]] = mul i32 [[A5]], [[A5]]742; CHECK-NEXT:    [[A7:%.*]] = mul i32 [[A6]], [[A6]]743; CHECK-NEXT:    [[A8:%.*]] = mul i32 [[A7]], [[A7]]744; CHECK-NEXT:    [[A9:%.*]] = mul i32 [[A8]], [[A8]]745; CHECK-NEXT:    [[A10:%.*]] = mul i32 [[A9]], [[A9]]746; CHECK-NEXT:    [[A11:%.*]] = mul i32 [[A10]], [[A10]]747; CHECK-NEXT:    [[A12:%.*]] = mul i32 [[A11]], [[A11]]748; CHECK-NEXT:    [[A13:%.*]] = mul i32 [[A12]], [[A12]]749; CHECK-NEXT:    [[A14:%.*]] = mul i32 [[A13]], [[A13]]750; CHECK-NEXT:    [[A15:%.*]] = mul i32 [[A14]], [[A14]]751; CHECK-NEXT:    [[A16:%.*]] = mul i32 [[A15]], [[A15]]752; CHECK-NEXT:    [[A17:%.*]] = mul i32 [[A16]], [[A16]]753; CHECK-NEXT:    [[A18:%.*]] = mul i32 [[A17]], [[A17]]754; CHECK-NEXT:    [[A19:%.*]] = mul i32 [[A18]], [[A18]]755; CHECK-NEXT:    [[A20:%.*]] = mul i32 [[A19]], [[A19]]756; CHECK-NEXT:    [[A21:%.*]] = mul i32 [[A20]], [[A20]]757; CHECK-NEXT:    [[A22:%.*]] = mul i32 [[A21]], [[A21]]758; CHECK-NEXT:    [[A23:%.*]] = mul i32 [[A22]], [[A22]]759; CHECK-NEXT:    [[A24:%.*]] = mul i32 [[A23]], [[A23]]760; CHECK-NEXT:    [[A25:%.*]] = mul i32 [[A24]], [[A24]]761; CHECK-NEXT:    [[A26:%.*]] = mul i32 [[A25]], [[A25]]762; CHECK-NEXT:    [[A27:%.*]] = mul i32 [[A26]], [[A26]]763; CHECK-NEXT:    [[A28:%.*]] = mul i32 [[A27]], [[A27]]764; CHECK-NEXT:    [[A29:%.*]] = mul i32 [[A28]], [[A28]]765; CHECK-NEXT:    [[A30:%.*]] = mul i32 [[A29]], [[A29]]766; CHECK-NEXT:    [[COND:%.*]] = trunc i32 [[A30]] to i1767; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND]]768; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()769; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]770; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]771; CHECK:       deopt:772; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]773; CHECK-NEXT:    ret void774; CHECK:       guarded:775; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()776; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND]], [[WIDENABLE_COND3]]777; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]778; CHECK:       deopt2:779; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]780; CHECK-NEXT:    ret void781; CHECK:       guarded1:782; CHECK-NEXT:    ret void783;784entry:785  %widenable_cond = call i1 @llvm.experimental.widenable.condition()786  %exiplicit_guard_cond = and i1 true, %widenable_cond787  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0788 789deopt:                                            ; preds = %entry790  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]791  ret void792 793guarded:                                          ; preds = %entry794  %a1 = mul i32 %a0, %a0795  %a2 = mul i32 %a1, %a1796  %a3 = mul i32 %a2, %a2797  %a4 = mul i32 %a3, %a3798  %a5 = mul i32 %a4, %a4799  %a6 = mul i32 %a5, %a5800  %a7 = mul i32 %a6, %a6801  %a8 = mul i32 %a7, %a7802  %a9 = mul i32 %a8, %a8803  %a10 = mul i32 %a9, %a9804  %a11 = mul i32 %a10, %a10805  %a12 = mul i32 %a11, %a11806  %a13 = mul i32 %a12, %a12807  %a14 = mul i32 %a13, %a13808  %a15 = mul i32 %a14, %a14809  %a16 = mul i32 %a15, %a15810  %a17 = mul i32 %a16, %a16811  %a18 = mul i32 %a17, %a17812  %a19 = mul i32 %a18, %a18813  %a20 = mul i32 %a19, %a19814  %a21 = mul i32 %a20, %a20815  %a22 = mul i32 %a21, %a21816  %a23 = mul i32 %a22, %a22817  %a24 = mul i32 %a23, %a23818  %a25 = mul i32 %a24, %a24819  %a26 = mul i32 %a25, %a25820  %a27 = mul i32 %a26, %a26821  %a28 = mul i32 %a27, %a27822  %a29 = mul i32 %a28, %a28823  %a30 = mul i32 %a29, %a29824  %cond = trunc i32 %a30 to i1825  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()826  %exiplicit_guard_cond4 = and i1 %cond, %widenable_cond3827  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0828 829deopt2:                                           ; preds = %guarded830  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]831  ret void832 833guarded1:                                         ; preds = %guarded834  ret void835}836 837define void @f_13(i32 %a, i1 %arg) {838; CHECK-LABEL: @f_13(839; CHECK-NEXT:  entry:840; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14841; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10842; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()843; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]844; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]845; CHECK:       deopt:846; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]847; CHECK-NEXT:    ret void848; CHECK:       guarded:849; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]850; CHECK:       left:851; CHECK-NEXT:    [[COND_1:%.*]] = icmp slt i32 [[A]], 10852; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()853; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]854; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]855; CHECK:       deopt2:856; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]857; CHECK-NEXT:    ret void858; CHECK:       guarded1:859; CHECK-NEXT:    ret void860; CHECK:       right:861; CHECK-NEXT:    ret void862;863entry:864  %cond_0 = icmp ult i32 %a, 14865  %widenable_cond = call i1 @llvm.experimental.widenable.condition()866  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond867  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0868 869deopt:                                            ; preds = %entry870  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]871  ret void872 873guarded:                                          ; preds = %entry874  br i1 %arg, label %left, label %right875 876left:                                             ; preds = %guarded877  %cond_1 = icmp slt i32 %a, 10878  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()879  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3880  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0881 882deopt2:                                           ; preds = %left883  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]884  ret void885 886guarded1:                                         ; preds = %left887  ret void888 889right:                                            ; preds = %guarded890  ret void891}892 893define void @f_14(i32 %a, i1 %arg) {894; CHECK-LABEL: @f_14(895; CHECK-NEXT:  entry:896; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14897; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()898; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]899; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]900; CHECK:       deopt:901; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]902; CHECK-NEXT:    ret void903; CHECK:       guarded:904; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]905; CHECK:       left:906; CHECK-NEXT:    [[COND_1:%.*]] = icmp sgt i32 [[A]], 10907; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()908; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]909; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]910; CHECK:       deopt2:911; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]912; CHECK-NEXT:    ret void913; CHECK:       guarded1:914; CHECK-NEXT:    ret void915; CHECK:       right:916; CHECK-NEXT:    ret void917;918entry:919  %cond_0 = icmp ult i32 %a, 14920  %widenable_cond = call i1 @llvm.experimental.widenable.condition()921  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond922  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0923 924deopt:                                            ; preds = %entry925  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]926  ret void927 928guarded:                                          ; preds = %entry929  br i1 %arg, label %left, label %right930 931left:                                             ; preds = %guarded932  %cond_1 = icmp sgt i32 %a, 10933  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()934  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3935  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0936 937deopt2:                                           ; preds = %left938  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]939  ret void940 941guarded1:                                         ; preds = %left942  ret void943 944right:                                            ; preds = %guarded945  ret void946}947 948; Make sure we do not widen guard by trivial true conditions into something.949define void @f_15(i1 %cond_0, i1 %cond_1) {950; CHECK-LABEL: @f_15(951; CHECK-NEXT:  entry:952; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()953; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]954; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]955; CHECK:       deopt:956; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]957; CHECK-NEXT:    ret void958; CHECK:       guarded:959; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()960; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 true, [[WIDENABLE_COND3]]961; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]962; CHECK:       deopt2:963; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]964; CHECK-NEXT:    ret void965; CHECK:       guarded1:966; CHECK-NEXT:    ret void967;968entry:969  %widenable_cond = call i1 @llvm.experimental.widenable.condition()970  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond971  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0972 973deopt:                                            ; preds = %entry974  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]975  ret void976 977guarded:                                          ; preds = %entry978  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()979  %exiplicit_guard_cond4 = and i1 true, %widenable_cond3980  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0981 982deopt2:                                           ; preds = %guarded983  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]984  ret void985 986guarded1:                                         ; preds = %guarded987  ret void988}989 990; Make sure we do not widen guard by trivial false conditions into something.991define void @f_16(i1 %cond_0, i1 %cond_1) {992; CHECK-LABEL: @f_16(993; CHECK-NEXT:  entry:994; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()995; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]996; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]997; CHECK:       deopt:998; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]999; CHECK-NEXT:    ret void1000; CHECK:       guarded:1001; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()1002; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 false, [[WIDENABLE_COND3]]1003; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]1004; CHECK:       deopt2:1005; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1006; CHECK-NEXT:    ret void1007; CHECK:       guarded1:1008; CHECK-NEXT:    ret void1009;1010entry:1011  %widenable_cond = call i1 @llvm.experimental.widenable.condition()1012  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond1013  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !01014 1015deopt:                                            ; preds = %entry1016  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1017  ret void1018 1019guarded:                                          ; preds = %entry1020  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()1021  %exiplicit_guard_cond4 = and i1 false, %widenable_cond31022  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !01023 1024deopt2:                                           ; preds = %guarded1025  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1026  ret void1027 1028guarded1:                                         ; preds = %guarded1029  ret void1030}1031 1032 1033define void @swapped_wb(i1 %cond_0, i1 %cond_1) {1034; CHECK-LABEL: @swapped_wb(1035; CHECK-NEXT:  entry:1036; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]1037; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]1038; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()1039; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[WIDE_CHK]]1040; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]1041; CHECK:       deopt:1042; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1043; CHECK-NEXT:    ret void1044; CHECK:       guarded:1045; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()1046; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]1047; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]1048; CHECK:       deopt2:1049; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1050; CHECK-NEXT:    ret void1051; CHECK:       guarded1:1052; CHECK-NEXT:    ret void1053;1054entry:1055  %widenable_cond = call i1 @llvm.experimental.widenable.condition()1056  %exiplicit_guard_cond = and i1 %widenable_cond, %cond_01057  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !01058 1059deopt:                                            ; preds = %entry1060  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1061  ret void1062 1063guarded:                                          ; preds = %entry1064  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()1065  %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond31066  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !01067 1068deopt2:                                           ; preds = %guarded1069  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1070  ret void1071 1072guarded1:                                         ; preds = %guarded1073  ret void1074}1075 1076define void @trivial_wb(i1 %cond_0) {1077; CHECK-LABEL: @trivial_wb(1078; CHECK-NEXT:  entry:1079; CHECK-NEXT:    [[COND_0_GW_FR:%.*]] = freeze i1 [[COND_0:%.*]]1080; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND_0_GW_FR]]1081; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()1082; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]1083; CHECK-NEXT:    br i1 [[TMP0]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]1084; CHECK:       deopt:1085; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1086; CHECK-NEXT:    ret void1087; CHECK:       guarded:1088; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()1089; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_0_GW_FR]], [[WIDENABLE_COND3]]1090; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]1091; CHECK:       deopt2:1092; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1093; CHECK-NEXT:    ret void1094; CHECK:       guarded1:1095; CHECK-NEXT:    ret void1096;1097entry:1098  %widenable_cond = call i1 @llvm.experimental.widenable.condition()1099  br i1 %widenable_cond, label %guarded, label %deopt, !prof !01100 1101deopt:                                            ; preds = %entry1102  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1103  ret void1104 1105guarded:                                          ; preds = %entry1106  %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()1107  %exiplicit_guard_cond4 = and i1 %cond_0, %widenable_cond31108  br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !01109 1110deopt2:                                           ; preds = %guarded1111  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]1112  ret void1113 1114guarded1:                                         ; preds = %guarded1115  ret void1116}1117 1118 1119declare void @llvm.experimental.deoptimize.isVoid(...)1120 1121; Function Attrs: inaccessiblememonly nounwind1122declare i1 @llvm.experimental.widenable.condition() #01123 1124attributes #0 = { inaccessiblememonly nounwind }1125 1126!0 = !{!"branch_weights", i32 1048576, i32 1}1127