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: [[V1:%.*]] = sub i32 [[C]], [[D]] 14; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]] 15; CHECK-NEXT: call void @sideeffect1() 16; CHECK-NEXT: ret i32 [[RES]] 17; 18entry: 19 call void @sideeffect0() 20 %cmp = icmp eq i32 %a, %b 21 br i1 %cmp, label %cond.true, label %cond.false 22 23cond.true: 24 %v0 = add i32 %c, %d 25 br label %end 26 27cond.false: 28 %v1 = sub i32 %c, %d 29 br label %end 30 31end: 32 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 33 call void @sideeffect1() 34 ret i32 %res 35} 36 37define i32 @predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) { 38; CHECK-LABEL: @predictably_taken( 39; CHECK-NEXT: entry: 40; CHECK-NEXT: call void @sideeffect0() 41; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 42; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF0:![0-9]+]] 43; CHECK: cond.true: 44; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 45; CHECK-NEXT: br label [[END:%.*]] 46; CHECK: cond.false: 47; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 48; CHECK-NEXT: br label [[END]] 49; CHECK: end: 50; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ] 51; CHECK-NEXT: call void @sideeffect1() 52; CHECK-NEXT: ret i32 [[RES]] 53; 54entry: 55 call void @sideeffect0() 56 %cmp = icmp eq i32 %a, %b 57 br i1 %cmp, label %cond.true, label %cond.false, !prof !0 ; likely branches to %cond.true 58 59cond.true: 60 %v0 = add i32 %c, %d 61 br label %end 62 63cond.false: 64 %v1 = sub i32 %c, %d 65 br label %end 66 67end: 68 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 69 call void @sideeffect1() 70 ret i32 %res 71} 72 73define i32 @almost_predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) { 74; CHECK-LABEL: @almost_predictably_taken( 75; CHECK-NEXT: entry: 76; CHECK-NEXT: call void @sideeffect0() 77; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 78; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 79; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 80; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF1:![0-9]+]] 81; CHECK-NEXT: call void @sideeffect1() 82; CHECK-NEXT: ret i32 [[RES]] 83; 84entry: 85 call void @sideeffect0() 86 %cmp = icmp eq i32 %a, %b 87 br i1 %cmp, label %cond.true, label %cond.false, !prof !1 ; almost likely branches to %cond.true 88 89cond.true: 90 %v0 = add i32 %c, %d 91 br label %end 92 93cond.false: 94 %v1 = sub i32 %c, %d 95 br label %end 96 97end: 98 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 99 call void @sideeffect1() 100 ret i32 %res 101} 102 103define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 104; CHECK-LABEL: @predictably_nontaken( 105; CHECK-NEXT: entry: 106; CHECK-NEXT: call void @sideeffect0() 107; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 108; CHECK-NEXT: br i1 [[CMP]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]] 109; CHECK: cond.true: 110; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 111; CHECK-NEXT: br label [[END:%.*]] 112; CHECK: cond.false: 113; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 114; CHECK-NEXT: br label [[END]] 115; CHECK: end: 116; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ] 117; CHECK-NEXT: call void @sideeffect1() 118; CHECK-NEXT: ret i32 [[RES]] 119; 120entry: 121 call void @sideeffect0() 122 %cmp = icmp eq i32 %a, %b 123 br i1 %cmp, label %cond.false, label %cond.true, !prof !0 ; likely branches to %cond.false 124 125cond.true: 126 %v0 = add i32 %c, %d 127 br label %end 128 129cond.false: 130 %v1 = sub i32 %c, %d 131 br label %end 132 133end: 134 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 135 call void @sideeffect1() 136 ret i32 %res 137} 138 139define i32 @almost_predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 140; CHECK-LABEL: @almost_predictably_nontaken( 141; CHECK-NEXT: entry: 142; CHECK-NEXT: call void @sideeffect0() 143; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 144; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 145; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 146; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF1]] 147; CHECK-NEXT: call void @sideeffect1() 148; CHECK-NEXT: ret i32 [[RES]] 149; 150entry: 151 call void @sideeffect0() 152 %cmp = icmp eq i32 %a, %b 153 br i1 %cmp, label %cond.false, label %cond.true, !prof !1 ; probably likely branches to %cond.false 154 155cond.true: 156 %v0 = add i32 %c, %d 157 br label %end 158 159cond.false: 160 %v1 = sub i32 %c, %d 161 br label %end 162 163end: 164 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 165 call void @sideeffect1() 166 ret i32 %res 167} 168 169define i32 @unpredictable(i32 %a, i32 %b, i32 %c, i32 %d) { 170; CHECK-LABEL: @unpredictable( 171; CHECK-NEXT: entry: 172; CHECK-NEXT: call void @sideeffect0() 173; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 174; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 175; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 176; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !unpredictable [[META2:![0-9]+]] 177; CHECK-NEXT: call void @sideeffect1() 178; CHECK-NEXT: ret i32 [[RES]] 179; 180entry: 181 call void @sideeffect0() 182 %cmp = icmp eq i32 %a, %b 183 br i1 %cmp, label %cond.true, label %cond.false, !unpredictable !2 ; unpredictable 184 185cond.true: 186 %v0 = add i32 %c, %d 187 br label %end 188 189cond.false: 190 %v1 = sub i32 %c, %d 191 br label %end 192 193end: 194 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 195 call void @sideeffect1() 196 ret i32 %res 197} 198 199define i32 @unpredictable_yet_taken(i32 %a, i32 %b, i32 %c, i32 %d) { 200; CHECK-LABEL: @unpredictable_yet_taken( 201; CHECK-NEXT: entry: 202; CHECK-NEXT: call void @sideeffect0() 203; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 204; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 205; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 206; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF0]], !unpredictable [[META2]] 207; CHECK-NEXT: call void @sideeffect1() 208; CHECK-NEXT: ret i32 [[RES]] 209; 210entry: 211 call void @sideeffect0() 212 %cmp = icmp eq i32 %a, %b 213 br i1 %cmp, label %cond.true, label %cond.false, !prof !0, !unpredictable !2 ; likely branches to %cond.true, yet unpredictable 214 215cond.true: 216 %v0 = add i32 %c, %d 217 br label %end 218 219cond.false: 220 %v1 = sub i32 %c, %d 221 br label %end 222 223end: 224 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 225 call void @sideeffect1() 226 ret i32 %res 227} 228 229define i32 @unpredictable_yet_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) { 230; CHECK-LABEL: @unpredictable_yet_nontaken( 231; CHECK-NEXT: entry: 232; CHECK-NEXT: call void @sideeffect0() 233; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 234; CHECK-NEXT: [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]] 235; CHECK-NEXT: [[V1:%.*]] = sub i32 [[C]], [[D]] 236; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF0]], !unpredictable [[META2]] 237; CHECK-NEXT: call void @sideeffect1() 238; CHECK-NEXT: ret i32 [[RES]] 239; 240entry: 241 call void @sideeffect0() 242 %cmp = icmp eq i32 %a, %b 243 br i1 %cmp, label %cond.false, label %cond.true, !prof !0, !unpredictable !2 ; likely branches to %cond.false, yet unpredictable 244 245cond.true: 246 %v0 = add i32 %c, %d 247 br label %end 248 249cond.false: 250 %v1 = sub i32 %c, %d 251 br label %end 252 253end: 254 %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ] 255 call void @sideeffect1() 256 ret i32 %res 257} 258 259!0 = !{!"branch_weights", i32 99, i32 1} 260!1 = !{!"branch_weights", i32 70, i32 1} 261!2 = !{} 262 263; CHECK: !0 = !{!"branch_weights", i32 99, i32 1} 264; CHECK: !1 = !{!"branch_weights", i32 70, i32 1} 265; CHECK: !2 = !{} 266