1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -two-entry-phi-node-folding-threshold=4 -phi-node-folding-threshold=0 < %s | FileCheck %s 3 4declare void @sideeffect0() 5declare void @sideeffect1() 6 7define i32 @unknown(i32 %a, i32 %b, i32 %c, i32 %d) { 8; CHECK-LABEL: @unknown( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: call void @sideeffect0() 11; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 12; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 13; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 0 14; CHECK-NEXT: call void @sideeffect1() 15; CHECK-NEXT: ret i32 [[RES]] 16; 17entry: 18 call void @sideeffect0() 19 %cmp = icmp eq i32 %a, %b 20 br i1 %cmp, label %cond.true, label %end 21 22cond.true: 23 %v0 = add i32 %c, %d 24 br label %end 25 26end: 27 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 28 call void @sideeffect1() 29 ret i32 %res 30} 31 32define i32 @predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) { 33; CHECK-LABEL: @predictably_taken( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: call void @sideeffect0() 36; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 37; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 38; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 0, !prof [[PROF0:![0-9]+]] 39; CHECK-NEXT: call void @sideeffect1() 40; CHECK-NEXT: ret i32 [[RES]] 41; 42entry: 43 call void @sideeffect0() 44 %cmp = icmp eq i32 %a, %b 45 br i1 %cmp, label %cond.true, label %end, !prof !0 ; likely branches to %cond.true 46 47cond.true: 48 %v0 = add i32 %c, %d 49 br label %end 50 51end: 52 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 53 call void @sideeffect1() 54 ret i32 %res 55} 56 57define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 58; CHECK-LABEL: @predictably_nontaken( 59; CHECK-NEXT: entry: 60; CHECK-NEXT: call void @sideeffect0() 61; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 62; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]] 63; CHECK: cond.true: 64; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 65; CHECK-NEXT: br label [[END]] 66; CHECK: end: 67; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 68; CHECK-NEXT: call void @sideeffect1() 69; CHECK-NEXT: ret i32 [[RES]] 70; 71entry: 72 call void @sideeffect0() 73 %cmp = icmp eq i32 %a, %b 74 br i1 %cmp, label %end, label %cond.true, !prof !0 ; likely branches to %end 75 76cond.true: 77 %v0 = add i32 %c, %d 78 br label %end 79 80end: 81 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 82 call void @sideeffect1() 83 ret i32 %res 84} 85 86define i32 @almost_predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 87; CHECK-LABEL: @almost_predictably_nontaken( 88; CHECK-NEXT: entry: 89; CHECK-NEXT: call void @sideeffect0() 90; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 91; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 92; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 [[V0]], !prof [[PROF1:![0-9]+]] 93; CHECK-NEXT: call void @sideeffect1() 94; CHECK-NEXT: ret i32 [[RES]] 95; 96entry: 97 call void @sideeffect0() 98 %cmp = icmp eq i32 %a, %b 99 br i1 %cmp, label %end, label %cond.true, !prof !1 ; probably likely branches to %end 100 101cond.true: 102 %v0 = add i32 %c, %d 103 br label %end 104 105end: 106 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 107 call void @sideeffect1() 108 ret i32 %res 109} 110 111define i32 @unpredictable(i32 %a, i32 %b, i32 %c, i32 %d) { 112; CHECK-LABEL: @unpredictable( 113; CHECK-NEXT: entry: 114; CHECK-NEXT: call void @sideeffect0() 115; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 116; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 117; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 0, !unpredictable [[META2:![0-9]+]] 118; CHECK-NEXT: call void @sideeffect1() 119; CHECK-NEXT: ret i32 [[RES]] 120; 121entry: 122 call void @sideeffect0() 123 %cmp = icmp eq i32 %a, %b 124 br i1 %cmp, label %cond.true, label %end, !unpredictable !2 ; unpredictable 125 126cond.true: 127 %v0 = add i32 %c, %d 128 br label %end 129 130end: 131 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 132 call void @sideeffect1() 133 ret i32 %res 134} 135 136define i32 @unpredictable_yet_taken(i32 %a, i32 %b, i32 %c, i32 %d) { 137; CHECK-LABEL: @unpredictable_yet_taken( 138; CHECK-NEXT: entry: 139; CHECK-NEXT: call void @sideeffect0() 140; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 141; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 142; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 0, !prof [[PROF0]], !unpredictable [[META2]] 143; CHECK-NEXT: call void @sideeffect1() 144; CHECK-NEXT: ret i32 [[RES]] 145; 146entry: 147 call void @sideeffect0() 148 %cmp = icmp eq i32 %a, %b 149 br i1 %cmp, label %cond.true, label %end, !prof !0, !unpredictable !2 ; likely branches to %cond.true, yet unpredictable 150 151cond.true: 152 %v0 = add i32 %c, %d 153 br label %end 154 155end: 156 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 157 call void @sideeffect1() 158 ret i32 %res 159} 160 161define i32 @unpredictable_yet_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 162; CHECK-LABEL: @unpredictable_yet_nontaken( 163; CHECK-NEXT: entry: 164; CHECK-NEXT: call void @sideeffect0() 165; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 166; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 167; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 [[V0]], !prof [[PROF0]], !unpredictable [[META2]] 168; CHECK-NEXT: call void @sideeffect1() 169; CHECK-NEXT: ret i32 [[RES]] 170; 171entry: 172 call void @sideeffect0() 173 %cmp = icmp eq i32 %a, %b 174 br i1 %cmp, label %end, label %cond.true, !prof !0, !unpredictable !2 ; likely branches to %end, yet unpredictable 175 176cond.true: 177 %v0 = add i32 %c, %d 178 br label %end 179 180end: 181 %res = phi i32 [ %v0, %cond.true ], [ 0, %entry ] 182 call void @sideeffect1() 183 ret i32 %res 184} 185 186!0 = !{!"branch_weights", i32 99, i32 1} 187!1 = !{!"branch_weights", i32 70, i32 1} 188!2 = !{} 189 190; CHECK: !0 = !{!"branch_weights", i32 99, i32 1} 191; CHECK: !1 = !{!"branch_weights", i32 70, i32 1} 192; CHECK: !2 = !{} 193