1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s 3 4define i32 @fshl(i32 %a, i32 %b, i32 %c) { 5; CHECK-LABEL: @fshl( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 8; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 9; CHECK: fshbb: 10; CHECK-NEXT: br label [[END]] 11; CHECK: end: 12; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[B:%.*]] 13; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]]) 14; CHECK-NEXT: ret i32 [[TMP1]] 15; 16entry: 17 %cmp = icmp eq i32 %c, 0 18 br i1 %cmp, label %end, label %fshbb 19 20fshbb: 21 %sub = sub i32 32, %c 22 %shr = lshr i32 %b, %sub 23 %shl = shl i32 %a, %c 24 %or = or i32 %shr, %shl 25 br label %end 26 27end: 28 %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ] 29 ret i32 %cond 30} 31 32define i32 @fshl_commute_phi(i32 %a, i32 %b, i32 %c) { 33; CHECK-LABEL: @fshl_commute_phi( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 36; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 37; CHECK: fshbb: 38; CHECK-NEXT: br label [[END]] 39; CHECK: end: 40; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[B:%.*]] 41; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]]) 42; CHECK-NEXT: ret i32 [[TMP1]] 43; 44entry: 45 %cmp = icmp eq i32 %c, 0 46 br i1 %cmp, label %end, label %fshbb 47 48fshbb: 49 %sub = sub i32 32, %c 50 %shr = lshr i32 %b, %sub 51 %shl = shl i32 %a, %c 52 %or = or i32 %shr, %shl 53 br label %end 54 55end: 56 %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ] 57 ret i32 %cond 58} 59 60define i32 @fshl_commute_or(i32 %a, i32 %b, i32 %c) { 61; CHECK-LABEL: @fshl_commute_or( 62; CHECK-NEXT: entry: 63; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 64; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 65; CHECK: fshbb: 66; CHECK-NEXT: br label [[END]] 67; CHECK: end: 68; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[B:%.*]] 69; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]]) 70; CHECK-NEXT: ret i32 [[TMP1]] 71; 72entry: 73 %cmp = icmp eq i32 %c, 0 74 br i1 %cmp, label %end, label %fshbb 75 76fshbb: 77 %sub = sub i32 32, %c 78 %shr = lshr i32 %b, %sub 79 %shl = shl i32 %a, %c 80 %or = or i32 %shl, %shr 81 br label %end 82 83end: 84 %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ] 85 ret i32 %cond 86} 87 88; Verify that the intrinsic is inserted into a valid position. 89 90define i32 @fshl_insert_valid_location(i32 %a, i32 %b, i32 %c) { 91; CHECK-LABEL: @fshl_insert_valid_location( 92; CHECK-NEXT: entry: 93; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 94; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 95; CHECK: fshbb: 96; CHECK-NEXT: br label [[END]] 97; CHECK: end: 98; CHECK-NEXT: [[OTHER:%.*]] = phi i32 [ 1, [[FSHBB]] ], [ 2, [[ENTRY:%.*]] ] 99; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[B:%.*]] 100; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]]) 101; CHECK-NEXT: [[RES:%.*]] = or i32 [[TMP1]], [[OTHER]] 102; CHECK-NEXT: ret i32 [[RES]] 103; 104entry: 105 %cmp = icmp eq i32 %c, 0 106 br i1 %cmp, label %end, label %fshbb 107 108fshbb: 109 %sub = sub i32 32, %c 110 %shr = lshr i32 %b, %sub 111 %shl = shl i32 %a, %c 112 %or = or i32 %shr, %shl 113 br label %end 114 115end: 116 %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ] 117 %other = phi i32 [ 1, %fshbb ], [ 2, %entry ] 118 %res = or i32 %cond, %other 119 ret i32 %res 120} 121 122define i32 @fshr(i32 %a, i32 %b, i32 %c) { 123; CHECK-LABEL: @fshr( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 126; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 127; CHECK: fshbb: 128; CHECK-NEXT: br label [[END]] 129; CHECK: end: 130; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[A:%.*]] 131; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]]) 132; CHECK-NEXT: ret i32 [[TMP1]] 133; 134entry: 135 %cmp = icmp eq i32 %c, 0 136 br i1 %cmp, label %end, label %fshbb 137 138fshbb: 139 %sub = sub i32 32, %c 140 %shl = shl i32 %a, %sub 141 %shr = lshr i32 %b, %c 142 %or = or i32 %shr, %shl 143 br label %end 144 145end: 146 %cond = phi i32 [ %or, %fshbb ], [ %b, %entry ] 147 ret i32 %cond 148} 149 150define i32 @fshr_commute_phi(i32 %a, i32 %b, i32 %c) { 151; CHECK-LABEL: @fshr_commute_phi( 152; CHECK-NEXT: entry: 153; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 154; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 155; CHECK: fshbb: 156; CHECK-NEXT: br label [[END]] 157; CHECK: end: 158; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[A:%.*]] 159; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]]) 160; CHECK-NEXT: ret i32 [[TMP1]] 161; 162entry: 163 %cmp = icmp eq i32 %c, 0 164 br i1 %cmp, label %end, label %fshbb 165 166fshbb: 167 %sub = sub i32 32, %c 168 %shl = shl i32 %a, %sub 169 %shr = lshr i32 %b, %c 170 %or = or i32 %shr, %shl 171 br label %end 172 173end: 174 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 175 ret i32 %cond 176} 177 178define i32 @fshr_commute_or(i32 %a, i32 %b, i32 %c) { 179; CHECK-LABEL: @fshr_commute_or( 180; CHECK-NEXT: entry: 181; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 182; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 183; CHECK: fshbb: 184; CHECK-NEXT: br label [[END]] 185; CHECK: end: 186; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[A:%.*]] 187; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]]) 188; CHECK-NEXT: ret i32 [[TMP1]] 189; 190entry: 191 %cmp = icmp eq i32 %c, 0 192 br i1 %cmp, label %end, label %fshbb 193 194fshbb: 195 %sub = sub i32 32, %c 196 %shl = shl i32 %a, %sub 197 %shr = lshr i32 %b, %c 198 %or = or i32 %shl, %shr 199 br label %end 200 201end: 202 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 203 ret i32 %cond 204} 205 206; Negative test - non-power-of-2 might require urem expansion in the backend. 207 208define i12 @could_be_fshr_weird_type(i12 %a, i12 %b, i12 %c) { 209; CHECK-LABEL: @could_be_fshr_weird_type( 210; CHECK-NEXT: entry: 211; CHECK-NEXT: [[CMP:%.*]] = icmp eq i12 [[C:%.*]], 0 212; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 213; CHECK: fshbb: 214; CHECK-NEXT: [[SUB:%.*]] = sub i12 12, [[C]] 215; CHECK-NEXT: [[SHL:%.*]] = shl i12 [[A:%.*]], [[SUB]] 216; CHECK-NEXT: [[SHR:%.*]] = lshr i12 [[B:%.*]], [[C]] 217; CHECK-NEXT: [[OR:%.*]] = or i12 [[SHL]], [[SHR]] 218; CHECK-NEXT: br label [[END]] 219; CHECK: end: 220; CHECK-NEXT: [[COND:%.*]] = phi i12 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 221; CHECK-NEXT: ret i12 [[COND]] 222; 223entry: 224 %cmp = icmp eq i12 %c, 0 225 br i1 %cmp, label %end, label %fshbb 226 227fshbb: 228 %sub = sub i12 12, %c 229 %shl = shl i12 %a, %sub 230 %shr = lshr i12 %b, %c 231 %or = or i12 %shl, %shr 232 br label %end 233 234end: 235 %cond = phi i12 [ %b, %entry ], [ %or, %fshbb ] 236 ret i12 %cond 237} 238 239; Negative test - wrong phi ops. 240 241define i32 @not_fshr_1(i32 %a, i32 %b, i32 %c) { 242; CHECK-LABEL: @not_fshr_1( 243; CHECK-NEXT: entry: 244; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 245; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 246; CHECK: fshbb: 247; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[C]] 248; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 249; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]] 250; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 251; CHECK-NEXT: br label [[END]] 252; CHECK: end: 253; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[C]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 254; CHECK-NEXT: ret i32 [[COND]] 255; 256entry: 257 %cmp = icmp eq i32 %c, 0 258 br i1 %cmp, label %end, label %fshbb 259 260fshbb: 261 %sub = sub i32 32, %c 262 %shl = shl i32 %a, %sub 263 %shr = lshr i32 %b, %c 264 %or = or i32 %shl, %shr 265 br label %end 266 267end: 268 %cond = phi i32 [ %c, %entry ], [ %or, %fshbb ] 269 ret i32 %cond 270} 271 272; Negative test - too many phi ops. 273 274define i32 @not_fshr_2(i32 %a, i32 %b, i32 %c, i32 %d) { 275; CHECK-LABEL: @not_fshr_2( 276; CHECK-NEXT: entry: 277; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 278; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 279; CHECK: fshbb: 280; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[C]] 281; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 282; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]] 283; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 284; CHECK-NEXT: [[CMP42:%.*]] = icmp ugt i32 [[OR]], 42 285; CHECK-NEXT: br i1 [[CMP42]], label [[END]], label [[BOGUS:%.*]] 286; CHECK: bogus: 287; CHECK-NEXT: br label [[END]] 288; CHECK: end: 289; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ], [ [[D:%.*]], [[BOGUS]] ] 290; CHECK-NEXT: ret i32 [[COND]] 291; 292entry: 293 %cmp = icmp eq i32 %c, 0 294 br i1 %cmp, label %end, label %fshbb 295 296fshbb: 297 %sub = sub i32 32, %c 298 %shl = shl i32 %a, %sub 299 %shr = lshr i32 %b, %c 300 %or = or i32 %shl, %shr 301 %cmp42 = icmp ugt i32 %or, 42 302 br i1 %cmp42, label %end, label %bogus 303 304bogus: 305 br label %end 306 307end: 308 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ], [ %d, %bogus ] 309 ret i32 %cond 310} 311 312; Negative test - wrong cmp (but this should match?). 313 314define i32 @not_fshr_3(i32 %a, i32 %b, i32 %c) { 315; CHECK-LABEL: @not_fshr_3( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[C:%.*]], 0 318; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 319; CHECK: fshbb: 320; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[C]] 321; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 322; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]] 323; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 324; CHECK-NEXT: br label [[END]] 325; CHECK: end: 326; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 327; CHECK-NEXT: ret i32 [[COND]] 328; 329entry: 330 %cmp = icmp sle i32 %c, 0 331 br i1 %cmp, label %end, label %fshbb 332 333fshbb: 334 %sub = sub i32 32, %c 335 %shl = shl i32 %a, %sub 336 %shr = lshr i32 %b, %c 337 %or = or i32 %shl, %shr 338 br label %end 339 340end: 341 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 342 ret i32 %cond 343} 344 345; Negative test - wrong shift. 346 347define i32 @not_fshr_4(i32 %a, i32 %b, i32 %c) { 348; CHECK-LABEL: @not_fshr_4( 349; CHECK-NEXT: entry: 350; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 351; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 352; CHECK: fshbb: 353; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[C]] 354; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 355; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[B:%.*]], [[C]] 356; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 357; CHECK-NEXT: br label [[END]] 358; CHECK: end: 359; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 360; CHECK-NEXT: ret i32 [[COND]] 361; 362entry: 363 %cmp = icmp eq i32 %c, 0 364 br i1 %cmp, label %end, label %fshbb 365 366fshbb: 367 %sub = sub i32 32, %c 368 %shl = shl i32 %a, %sub 369 %shr = ashr i32 %b, %c 370 %or = or i32 %shl, %shr 371 br label %end 372 373end: 374 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 375 ret i32 %cond 376} 377 378; Negative test - wrong shift for rotate (but can be folded to a generic funnel shift). 379 380define i32 @not_fshr_5(i32 %a, i32 %b, i32 %c) { 381; CHECK-LABEL: @not_fshr_5( 382; CHECK-NEXT: entry: 383; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 384; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 385; CHECK: fshbb: 386; CHECK-NEXT: br label [[END]] 387; CHECK: end: 388; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.fshr.i32(i32 [[C]], i32 [[B:%.*]], i32 [[C]]) 389; CHECK-NEXT: ret i32 [[TMP0]] 390; 391entry: 392 %cmp = icmp eq i32 %c, 0 393 br i1 %cmp, label %end, label %fshbb 394 395fshbb: 396 %sub = sub i32 32, %c 397 %shl = shl i32 %c, %sub 398 %shr = lshr i32 %b, %c 399 %or = or i32 %shl, %shr 400 br label %end 401 402end: 403 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 404 ret i32 %cond 405} 406 407; Negative test - wrong sub. 408 409define i32 @not_fshr_6(i32 %a, i32 %b, i32 %c) { 410; CHECK-LABEL: @not_fshr_6( 411; CHECK-NEXT: entry: 412; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 413; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 414; CHECK: fshbb: 415; CHECK-NEXT: [[SUB:%.*]] = sub i32 8, [[C]] 416; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 417; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]] 418; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 419; CHECK-NEXT: br label [[END]] 420; CHECK: end: 421; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 422; CHECK-NEXT: ret i32 [[COND]] 423; 424entry: 425 %cmp = icmp eq i32 %c, 0 426 br i1 %cmp, label %end, label %fshbb 427 428fshbb: 429 %sub = sub i32 8, %c 430 %shl = shl i32 %a, %sub 431 %shr = lshr i32 %b, %c 432 %or = or i32 %shl, %shr 433 br label %end 434 435end: 436 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 437 ret i32 %cond 438} 439 440; Negative test - extra use. Technically, we could transform this 441; because it doesn't increase the instruction count, but we're 442; being cautious not to cause a potential perf pessimization for 443; targets that do not have a fshate instruction. 444 445define i32 @could_be_fshr(i32 %a, i32 %b, i32 %c, ptr %p) { 446; CHECK-LABEL: @could_be_fshr( 447; CHECK-NEXT: entry: 448; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 449; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]] 450; CHECK: fshbb: 451; CHECK-NEXT: [[SUB:%.*]] = sub i32 32, [[C]] 452; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]] 453; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]] 454; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR]] 455; CHECK-NEXT: store i32 [[OR]], ptr [[P:%.*]], align 4 456; CHECK-NEXT: br label [[END]] 457; CHECK: end: 458; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ] 459; CHECK-NEXT: ret i32 [[COND]] 460; 461entry: 462 %cmp = icmp eq i32 %c, 0 463 br i1 %cmp, label %end, label %fshbb 464 465fshbb: 466 %sub = sub i32 32, %c 467 %shl = shl i32 %a, %sub 468 %shr = lshr i32 %b, %c 469 %or = or i32 %shl, %shr 470 store i32 %or, ptr %p 471 br label %end 472 473end: 474 %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ] 475 ret i32 %cond 476} 477 478; PR48068 - Ensure we don't fold a funnel shift that depends on a shift value that 479; can't be hoisted out of a basic block. 480@a = global i32 0, align 4 481declare i32 @i(...) 482declare i32 @f(...) 483 484define i32 @PR48068() { 485; CHECK-LABEL: @PR48068( 486; CHECK-NEXT: entry: 487; CHECK-NEXT: [[CALL:%.*]] = call i32 @i() 488; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 489; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0 490; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 491; CHECK: if.then: 492; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[CALL]], [[TMP0]] 493; CHECK-NEXT: [[CALL_I:%.*]] = call i32 @f() 494; CHECK-NEXT: [[SUB_I:%.*]] = sub nsw i32 32, [[TMP0]] 495; CHECK-NEXT: [[SHR_I:%.*]] = lshr i32 [[CALL_I]], [[SUB_I]] 496; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], [[SHR_I]] 497; CHECK-NEXT: br label [[IF_END]] 498; CHECK: if.end: 499; CHECK-NEXT: [[H_0:%.*]] = phi i32 [ [[OR]], [[IF_THEN]] ], [ [[CALL]], [[ENTRY:%.*]] ] 500; CHECK-NEXT: ret i32 [[H_0]] 501; 502entry: 503 %call = call i32 @i() 504 %0 = load i32, ptr @a, align 4 505 %tobool.not = icmp eq i32 %0, 0 506 br i1 %tobool.not, label %if.end, label %if.then 507 508if.then: ; preds = %entry 509 %shl = shl i32 %call, %0 510 %call.i = call i32 @f() 511 %sub.i = sub nsw i32 32, %0 512 %shr.i = lshr i32 %call.i, %sub.i 513 %or = or i32 %shl, %shr.i 514 br label %if.end 515 516if.end: ; preds = %if.then, %entry 517 %h.0 = phi i32 [ %or, %if.then ], [ %call, %entry ] 518 ret i32 %h.0 519} 520