brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.1 KiB · b1bc5f4 Raw
520 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s3 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:%.*]], 08; 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, 018  br i1 %cmp, label %end, label %fshbb19 20fshbb:21  %sub = sub i32 32, %c22  %shr = lshr i32 %b, %sub23  %shl = shl i32 %a, %c24  %or = or i32 %shr, %shl25  br label %end26 27end:28  %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ]29  ret i32 %cond30}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:%.*]], 036; 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, 046  br i1 %cmp, label %end, label %fshbb47 48fshbb:49  %sub = sub i32 32, %c50  %shr = lshr i32 %b, %sub51  %shl = shl i32 %a, %c52  %or = or i32 %shr, %shl53  br label %end54 55end:56  %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ]57  ret i32 %cond58}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:%.*]], 064; 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, 074  br i1 %cmp, label %end, label %fshbb75 76fshbb:77  %sub = sub i32 32, %c78  %shr = lshr i32 %b, %sub79  %shl = shl i32 %a, %c80  %or = or i32 %shl, %shr81  br label %end82 83end:84  %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ]85  ret i32 %cond86}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:%.*]], 094; 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, 0106  br i1 %cmp, label %end, label %fshbb107 108fshbb:109  %sub = sub i32 32, %c110  %shr = lshr i32 %b, %sub111  %shl = shl i32 %a, %c112  %or = or i32 %shr, %shl113  br label %end114 115end:116  %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ]117  %other = phi i32 [ 1, %fshbb ], [ 2, %entry ]118  %res = or i32 %cond, %other119  ret i32 %res120}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:%.*]], 0126; 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, 0136  br i1 %cmp, label %end, label %fshbb137 138fshbb:139  %sub = sub i32 32, %c140  %shl = shl i32 %a, %sub141  %shr = lshr i32 %b, %c142  %or = or i32 %shr, %shl143  br label %end144 145end:146  %cond = phi i32 [ %or, %fshbb ], [ %b, %entry ]147  ret i32 %cond148}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:%.*]], 0154; 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, 0164  br i1 %cmp, label %end, label %fshbb165 166fshbb:167  %sub = sub i32 32, %c168  %shl = shl i32 %a, %sub169  %shr = lshr i32 %b, %c170  %or = or i32 %shr, %shl171  br label %end172 173end:174  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]175  ret i32 %cond176}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:%.*]], 0182; 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, 0192  br i1 %cmp, label %end, label %fshbb193 194fshbb:195  %sub = sub i32 32, %c196  %shl = shl i32 %a, %sub197  %shr = lshr i32 %b, %c198  %or = or i32 %shl, %shr199  br label %end200 201end:202  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]203  ret i32 %cond204}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:%.*]], 0212; 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, 0225  br i1 %cmp, label %end, label %fshbb226 227fshbb:228  %sub = sub i12 12, %c229  %shl = shl i12 %a, %sub230  %shr = lshr i12 %b, %c231  %or = or i12 %shl, %shr232  br label %end233 234end:235  %cond = phi i12 [ %b, %entry ], [ %or, %fshbb ]236  ret i12 %cond237}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:%.*]], 0245; 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, 0258  br i1 %cmp, label %end, label %fshbb259 260fshbb:261  %sub = sub i32 32, %c262  %shl = shl i32 %a, %sub263  %shr = lshr i32 %b, %c264  %or = or i32 %shl, %shr265  br label %end266 267end:268  %cond = phi i32 [ %c, %entry ], [ %or, %fshbb ]269  ret i32 %cond270}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:%.*]], 0278; 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]], 42285; 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, 0294  br i1 %cmp, label %end, label %fshbb295 296fshbb:297  %sub = sub i32 32, %c298  %shl = shl i32 %a, %sub299  %shr = lshr i32 %b, %c300  %or = or i32 %shl, %shr301  %cmp42 = icmp ugt i32 %or, 42302  br i1 %cmp42, label %end, label %bogus303 304bogus:305  br label %end306 307end:308  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ], [ %d, %bogus ]309  ret i32 %cond310}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:%.*]], 0318; 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, 0331  br i1 %cmp, label %end, label %fshbb332 333fshbb:334  %sub = sub i32 32, %c335  %shl = shl i32 %a, %sub336  %shr = lshr i32 %b, %c337  %or = or i32 %shl, %shr338  br label %end339 340end:341  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]342  ret i32 %cond343}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:%.*]], 0351; 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, 0364  br i1 %cmp, label %end, label %fshbb365 366fshbb:367  %sub = sub i32 32, %c368  %shl = shl i32 %a, %sub369  %shr = ashr i32 %b, %c370  %or = or i32 %shl, %shr371  br label %end372 373end:374  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]375  ret i32 %cond376}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:%.*]], 0384; 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, 0393  br i1 %cmp, label %end, label %fshbb394 395fshbb:396  %sub = sub i32 32, %c397  %shl = shl i32 %c, %sub398  %shr = lshr i32 %b, %c399  %or = or i32 %shl, %shr400  br label %end401 402end:403  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]404  ret i32 %cond405}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:%.*]], 0413; 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, 0426  br i1 %cmp, label %end, label %fshbb427 428fshbb:429  %sub = sub i32 8, %c430  %shl = shl i32 %a, %sub431  %shr = lshr i32 %b, %c432  %or = or i32 %shl, %shr433  br label %end434 435end:436  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]437  ret i32 %cond438}439 440; Negative test - extra use. Technically, we could transform this441; because it doesn't increase the instruction count, but we're442; being cautious not to cause a potential perf pessimization for443; 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:%.*]], 0449; 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 4456; 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, 0463  br i1 %cmp, label %end, label %fshbb464 465fshbb:466  %sub = sub i32 32, %c467  %shl = shl i32 %a, %sub468  %shr = lshr i32 %b, %c469  %or = or i32 %shl, %shr470  store i32 %or, ptr %p471  br label %end472 473end:474  %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]475  ret i32 %cond476}477 478; PR48068 - Ensure we don't fold a funnel shift that depends on a shift value that479; can't be hoisted out of a basic block.480@a = global i32 0, align 4481declare 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 4489; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0490; 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 4505  %tobool.not = icmp eq i32 %0, 0506  br i1 %tobool.not, label %if.end, label %if.then507 508if.then:                                          ; preds = %entry509  %shl = shl i32 %call, %0510  %call.i = call i32 @f()511  %sub.i = sub nsw i32 32, %0512  %shr.i = lshr i32 %call.i, %sub.i513  %or = or i32 %shl, %shr.i514  br label %if.end515 516if.end:                                           ; preds = %if.then, %entry517  %h.0 = phi i32 [ %or, %if.then ], [ %call, %entry ]518  ret i32 %h.0519}520