brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.9 KiB · 6249111 Raw
887 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=gvn-hoist -S < %s | FileCheck %s3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"4target triple = "x86_64-unknown-linux-gnu"5 6@GlobalVar = internal global float 1.000000e+007 8; Check that all scalar expressions are hoisted.9define float @scalarsHoisting(float %d, float %min, float %max, float %a) {10; CHECK-LABEL: @scalarsHoisting(11; CHECK-NEXT:  entry:12; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]13; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+0014; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[MIN:%.*]], [[A:%.*]]15; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]16; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[MAX:%.*]], [[A]]17; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]18; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]19; CHECK:       if.then:20; CHECK-NEXT:    br label [[IF_END:%.*]]21; CHECK:       if.else:22; CHECK-NEXT:    br label [[IF_END]]23; CHECK:       if.end:24; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]25; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]26; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]27; CHECK-NEXT:    ret float [[ADD]]28;29entry:30  %div = fdiv float 1.000000e+00, %d31  %cmp = fcmp oge float %div, 0.000000e+0032  br i1 %cmp, label %if.then, label %if.else33 34if.then:                                          ; preds = %entry35  %sub = fsub float %min, %a36  %mul = fmul float %sub, %div37  %sub1 = fsub float %max, %a38  %mul2 = fmul float %sub1, %div39  br label %if.end40 41if.else:                                          ; preds = %entry42  %sub3 = fsub float %max, %a43  %mul4 = fmul float %sub3, %div44  %sub5 = fsub float %min, %a45  %mul6 = fmul float %sub5, %div46  br label %if.end47 48if.end:                                           ; preds = %if.else, %if.then49  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]50  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]51  %add = fadd float %tmax.0, %tmin.052  ret float %add53}54 55; Check that all loads and scalars depending on the loads are hoisted.56; Check that getelementptr computation gets hoisted before the load.57define float @readsAndScalarsHoisting(float %d, ptr %min, ptr %max, ptr %a) {58; CHECK-LABEL: @readsAndScalarsHoisting(59; CHECK-NEXT:  entry:60; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]61; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+0062; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[MIN:%.*]], i32 163; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[TMP0]], align 464; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[A:%.*]], align 465; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX:%.*]], align 466; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP1]], [[TMP2]]67; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]68; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP3]], [[TMP2]]69; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]70; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]71; CHECK:       if.then:72; CHECK-NEXT:    [[A:%.*]] = getelementptr float, ptr [[MIN]], i32 173; CHECK-NEXT:    br label [[IF_END:%.*]]74; CHECK:       if.else:75; CHECK-NEXT:    [[B:%.*]] = getelementptr float, ptr [[MIN]], i32 176; CHECK-NEXT:    br label [[IF_END]]77; CHECK:       if.end:78; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]79; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]80; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]81; CHECK-NEXT:    ret float [[ADD]]82;83entry:84  %div = fdiv float 1.000000e+00, %d85  %cmp = fcmp oge float %div, 0.000000e+0086  br i1 %cmp, label %if.then, label %if.else87 88if.then:                                          ; preds = %entry89  %A = getelementptr float, ptr %min, i32 190  %0 = load float, ptr %A, align 491  %1 = load float, ptr %a, align 492  %sub = fsub float %0, %193  %mul = fmul float %sub, %div94  %2 = load float, ptr %max, align 495  %sub1 = fsub float %2, %196  %mul2 = fmul float %sub1, %div97  br label %if.end98 99if.else:                                          ; preds = %entry100  %3 = load float, ptr %max, align 4101  %4 = load float, ptr %a, align 4102  %sub3 = fsub float %3, %4103  %mul4 = fmul float %sub3, %div104  %B = getelementptr float, ptr %min, i32 1105  %5 = load float, ptr %B, align 4106  %sub5 = fsub float %5, %4107  %mul6 = fmul float %sub5, %div108  br label %if.end109 110if.end:                                           ; preds = %if.else, %if.then111  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]112  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]113  %add = fadd float %tmax.0, %tmin.0114  ret float %add115}116 117; Check that we do not hoist loads after a store: the first two loads will be118; hoisted, and then the third load will not be hoisted.119define float @readsAndWrites(float %d, ptr %min, ptr %max, ptr %a) {120; CHECK-LABEL: @readsAndWrites(121; CHECK-NEXT:  entry:122; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]123; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00124; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4125; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4126; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]127; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]128; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]129; CHECK:       if.then:130; CHECK-NEXT:    store float [[TMP0]], ptr @GlobalVar, align 4131; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4132; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]133; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]134; CHECK-NEXT:    br label [[IF_END:%.*]]135; CHECK:       if.else:136; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4137; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP1]]138; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]139; CHECK-NEXT:    br label [[IF_END]]140; CHECK:       if.end:141; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]142; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]143; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]144; CHECK-NEXT:    ret float [[ADD]]145;146entry:147  %div = fdiv float 1.000000e+00, %d148  %cmp = fcmp oge float %div, 0.000000e+00149  br i1 %cmp, label %if.then, label %if.else150 151if.then:                                          ; preds = %entry152  %0 = load float, ptr %min, align 4153  %1 = load float, ptr %a, align 4154  store float %0, ptr @GlobalVar155  %sub = fsub float %0, %1156  %mul = fmul float %sub, %div157  %2 = load float, ptr %max, align 4158  %sub1 = fsub float %2, %1159  %mul2 = fmul float %sub1, %div160  br label %if.end161 162if.else:                                          ; preds = %entry163  %3 = load float, ptr %max, align 4164  %4 = load float, ptr %a, align 4165  %sub3 = fsub float %3, %4166  %mul4 = fmul float %sub3, %div167  %5 = load float, ptr %min, align 4168  %sub5 = fsub float %5, %4169  %mul6 = fmul float %sub5, %div170  br label %if.end171 172if.end:                                           ; preds = %if.else, %if.then173  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]174  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]175  %add = fadd float %tmax.0, %tmin.0176  ret float %add177}178 179; Check that we do hoist loads when the store is above the insertion point.180define float @readsAndWriteAboveInsertPt(float %d, ptr %min, ptr %max, ptr %a) {181; CHECK-LABEL: @readsAndWriteAboveInsertPt(182; CHECK-NEXT:  entry:183; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]184; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4185; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00186; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4187; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4188; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4189; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]190; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]191; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]192; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]193; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]194; CHECK:       if.then:195; CHECK-NEXT:    br label [[IF_END:%.*]]196; CHECK:       if.else:197; CHECK-NEXT:    br label [[IF_END]]198; CHECK:       if.end:199; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]200; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]201; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]202; CHECK-NEXT:    ret float [[ADD]]203;204entry:205  %div = fdiv float 1.000000e+00, %d206  store float 0.000000e+00, ptr @GlobalVar207  %cmp = fcmp oge float %div, 0.000000e+00208  br i1 %cmp, label %if.then, label %if.else209 210if.then:                                          ; preds = %entry211  %0 = load float, ptr %min, align 4212  %1 = load float, ptr %a, align 4213  %sub = fsub float %0, %1214  %mul = fmul float %sub, %div215  %2 = load float, ptr %max, align 4216  %sub1 = fsub float %2, %1217  %mul2 = fmul float %sub1, %div218  br label %if.end219 220if.else:                                          ; preds = %entry221  %3 = load float, ptr %max, align 4222  %4 = load float, ptr %a, align 4223  %sub3 = fsub float %3, %4224  %mul4 = fmul float %sub3, %div225  %5 = load float, ptr %min, align 4226  %sub5 = fsub float %5, %4227  %mul6 = fmul float %sub5, %div228  br label %if.end229 230if.end:                                           ; preds = %if.else, %if.then231  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]232  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]233  %add = fadd float %tmax.0, %tmin.0234  ret float %add235}236 237; Check that dependent expressions are hoisted.238define float @dependentScalarsHoisting(float %a, float %b, i1 %c) {239; CHECK-LABEL: @dependentScalarsHoisting(240; CHECK-NEXT:  entry:241; CHECK-NEXT:    [[D:%.*]] = fsub float [[B:%.*]], [[A:%.*]]242; CHECK-NEXT:    [[E:%.*]] = fadd float [[D]], [[A]]243; CHECK-NEXT:    [[F:%.*]] = fdiv float [[E]], [[A]]244; CHECK-NEXT:    [[G:%.*]] = fmul float [[F]], [[A]]245; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]246; CHECK:       if.then:247; CHECK-NEXT:    br label [[IF_END:%.*]]248; CHECK:       if.else:249; CHECK-NEXT:    br label [[IF_END]]250; CHECK:       if.end:251; CHECK-NEXT:    [[R:%.*]] = phi float [ [[G]], [[IF_THEN]] ], [ [[G]], [[IF_ELSE]] ]252; CHECK-NEXT:    ret float [[R]]253;254entry:255  br i1 %c, label %if.then, label %if.else256 257if.then:258  %d = fsub float %b, %a259  %e = fadd float %d, %a260  %f = fdiv float %e, %a261  %g = fmul float %f, %a262  br label %if.end263 264if.else:265  %h = fsub float %b, %a266  %i = fadd float %h, %a267  %j = fdiv float %i, %a268  %k = fmul float %j, %a269  br label %if.end270 271if.end:272  %r = phi float [ %g, %if.then ], [ %k, %if.else ]273  ret float %r274}275 276; Check that all independent expressions are hoisted.277define float @independentScalarsHoisting(float %a, float %b, i1 %c) {278; CHECK-LABEL: @independentScalarsHoisting(279; CHECK-NEXT:  entry:280; CHECK-NEXT:    [[D:%.*]] = fadd float [[B:%.*]], [[A:%.*]]281; CHECK-NEXT:    [[E:%.*]] = fsub float [[B]], [[A]]282; CHECK-NEXT:    [[F:%.*]] = fdiv float [[B]], [[A]]283; CHECK-NEXT:    [[G:%.*]] = fmul float [[B]], [[A]]284; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]285; CHECK:       if.then:286; CHECK-NEXT:    br label [[IF_END:%.*]]287; CHECK:       if.else:288; CHECK-NEXT:    br label [[IF_END]]289; CHECK:       if.end:290; CHECK-NEXT:    [[P:%.*]] = phi float [ [[D]], [[IF_THEN]] ], [ [[D]], [[IF_ELSE]] ]291; CHECK-NEXT:    [[Q:%.*]] = phi float [ [[E]], [[IF_THEN]] ], [ [[E]], [[IF_ELSE]] ]292; CHECK-NEXT:    [[R:%.*]] = phi float [ [[F]], [[IF_THEN]] ], [ [[F]], [[IF_ELSE]] ]293; CHECK-NEXT:    [[S:%.*]] = phi float [ [[G]], [[IF_THEN]] ], [ [[G]], [[IF_ELSE]] ]294; CHECK-NEXT:    [[T:%.*]] = fadd float [[P]], [[Q]]295; CHECK-NEXT:    [[U:%.*]] = fadd float [[R]], [[S]]296; CHECK-NEXT:    [[V:%.*]] = fadd float [[T]], [[U]]297; CHECK-NEXT:    ret float [[V]]298;299entry:300  br i1 %c, label %if.then, label %if.else301 302if.then:303  %d = fadd float %b, %a304  %e = fsub float %b, %a305  %f = fdiv float %b, %a306  %g = fmul float %b, %a307  br label %if.end308 309if.else:310  %i = fadd float %b, %a311  %h = fsub float %b, %a312  %j = fdiv float %b, %a313  %k = fmul float %b, %a314  br label %if.end315 316if.end:317  %p = phi float [ %d, %if.then ], [ %i, %if.else ]318  %q = phi float [ %e, %if.then ], [ %h, %if.else ]319  %r = phi float [ %f, %if.then ], [ %j, %if.else ]320  %s = phi float [ %g, %if.then ], [ %k, %if.else ]321  %t = fadd float %p, %q322  %u = fadd float %r, %s323  %v = fadd float %t, %u324  ret float %v325}326 327; Check that we hoist load and scalar expressions in triangles.328define float @triangleHoisting(float %d, ptr %min, ptr %max, ptr %a) {329; CHECK-LABEL: @triangleHoisting(330; CHECK-NEXT:  entry:331; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]332; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00333; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4334; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4335; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4336; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP0]], [[TMP1]]337; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]338; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP2]], [[TMP1]]339; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]340; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]341; CHECK:       if.then:342; CHECK-NEXT:    br label [[IF_END]]343; CHECK:       if.end:344; CHECK-NEXT:    [[P1:%.*]] = phi float [ [[MUL4]], [[IF_THEN]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]345; CHECK-NEXT:    [[P2:%.*]] = phi float [ [[MUL6]], [[IF_THEN]] ], [ 0.000000e+00, [[ENTRY]] ]346; CHECK-NEXT:    [[X:%.*]] = fadd float [[P1]], [[MUL6]]347; CHECK-NEXT:    [[Y:%.*]] = fadd float [[P2]], [[MUL4]]348; CHECK-NEXT:    [[Z:%.*]] = fadd float [[X]], [[Y]]349; CHECK-NEXT:    ret float [[Z]]350;351entry:352  %div = fdiv float 1.000000e+00, %d353  %cmp = fcmp oge float %div, 0.000000e+00354  br i1 %cmp, label %if.then, label %if.end355 356if.then:                                          ; preds = %entry357  %0 = load float, ptr %min, align 4358  %1 = load float, ptr %a, align 4359  %sub = fsub float %0, %1360  %mul = fmul float %sub, %div361  %2 = load float, ptr %max, align 4362  %sub1 = fsub float %2, %1363  %mul2 = fmul float %sub1, %div364  br label %if.end365 366if.end:                                          ; preds = %entry367  %p1 = phi float [ %mul2, %if.then ], [ 0.000000e+00, %entry ]368  %p2 = phi float [ %mul, %if.then ], [ 0.000000e+00, %entry ]369  %3 = load float, ptr %max, align 4370  %4 = load float, ptr %a, align 4371  %sub3 = fsub float %3, %4372  %mul4 = fmul float %sub3, %div373  %5 = load float, ptr %min, align 4374  %sub5 = fsub float %5, %4375  %mul6 = fmul float %sub5, %div376 377  %x = fadd float %p1, %mul6378  %y = fadd float %p2, %mul4379  %z = fadd float %x, %y380  ret float %z381}382 383; Check that we do not hoist loads past stores within a same basic block.384define i32 @noHoistInSingleBBWithStore() {385; CHECK-LABEL: @noHoistInSingleBBWithStore(386; CHECK-NEXT:  entry:387; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4388; CHECK-NEXT:    [[TMP0:%.*]] = bitcast ptr [[D]] to ptr389; CHECK-NEXT:    [[BF:%.*]] = load i8, ptr [[TMP0]], align 4390; CHECK-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF]], -3391; CHECK-NEXT:    store i8 [[BF_CLEAR]], ptr [[TMP0]], align 4392; CHECK-NEXT:    [[BF1:%.*]] = load i8, ptr [[TMP0]], align 4393; CHECK-NEXT:    [[BF_CLEAR1:%.*]] = and i8 [[BF1]], 1394; CHECK-NEXT:    store i8 [[BF_CLEAR1]], ptr [[TMP0]], align 4395; CHECK-NEXT:    ret i32 0396;397entry:398  %D = alloca i32, align 4399  %0 = bitcast ptr %D to ptr400  %bf = load i8, ptr %0, align 4401  %bf.clear = and i8 %bf, -3402  store i8 %bf.clear, ptr %0, align 4403  %bf1 = load i8, ptr %0, align 4404  %bf.clear1 = and i8 %bf1, 1405  store i8 %bf.clear1, ptr %0, align 4406  ret i32 0407}408 409; Check that we do not hoist loads past calls within a same basic block.410declare void @foo()411define i32 @noHoistInSingleBBWithCall() {412; CHECK-LABEL: @noHoistInSingleBBWithCall(413; CHECK-NEXT:  entry:414; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4415; CHECK-NEXT:    [[TMP0:%.*]] = bitcast ptr [[D]] to ptr416; CHECK-NEXT:    [[BF:%.*]] = load i8, ptr [[TMP0]], align 4417; CHECK-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF]], -3418; CHECK-NEXT:    call void @foo()419; CHECK-NEXT:    [[BF1:%.*]] = load i8, ptr [[TMP0]], align 4420; CHECK-NEXT:    [[BF_CLEAR1:%.*]] = and i8 [[BF1]], 1421; CHECK-NEXT:    ret i32 0422;423entry:424  %D = alloca i32, align 4425  %0 = bitcast ptr %D to ptr426  %bf = load i8, ptr %0, align 4427  %bf.clear = and i8 %bf, -3428  call void @foo()429  %bf1 = load i8, ptr %0, align 4430  %bf.clear1 = and i8 %bf1, 1431  ret i32 0432}433 434; Check that we do not hoist loads past stores in any branch of a diamond.435define float @noHoistInDiamondWithOneStore1(float %d, ptr %min, ptr %max, ptr %a) {436; CHECK-LABEL: @noHoistInDiamondWithOneStore1(437; CHECK-NEXT:  entry:438; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]439; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00440; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]441; CHECK:       if.then:442; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4443; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4444; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4445; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]446; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]447; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4448; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]449; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]450; CHECK-NEXT:    br label [[IF_END:%.*]]451; CHECK:       if.else:452; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4453; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4454; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]455; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]456; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4457; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]458; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]459; CHECK-NEXT:    br label [[IF_END]]460; CHECK:       if.end:461; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL6]], [[IF_ELSE]] ]462; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]463; CHECK-NEXT:    [[TMP6:%.*]] = load float, ptr [[MAX]], align 4464; CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr [[A]], align 4465; CHECK-NEXT:    [[SUB6:%.*]] = fsub float [[TMP6]], [[TMP7]]466; CHECK-NEXT:    [[MUL7:%.*]] = fmul float [[SUB6]], [[DIV]]467; CHECK-NEXT:    [[TMP8:%.*]] = load float, ptr [[MIN]], align 4468; CHECK-NEXT:    [[SUB8:%.*]] = fsub float [[TMP8]], [[TMP7]]469; CHECK-NEXT:    [[MUL9:%.*]] = fmul float [[SUB8]], [[DIV]]470; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]471; CHECK-NEXT:    ret float [[ADD]]472;473entry:474  %div = fdiv float 1.000000e+00, %d475  %cmp = fcmp oge float %div, 0.000000e+00476  br i1 %cmp, label %if.then, label %if.else477 478if.then:                                          ; preds = %entry479  store float 0.000000e+00, ptr @GlobalVar480  %0 = load float, ptr %min, align 4481  %1 = load float, ptr %a, align 4482  %sub = fsub float %0, %1483  %mul = fmul float %sub, %div484  %2 = load float, ptr %max, align 4485  %sub1 = fsub float %2, %1486  %mul2 = fmul float %sub1, %div487  br label %if.end488 489if.else:                                          ; preds = %entry490  ; There are no side effects on the if.else branch.491  %3 = load float, ptr %max, align 4492  %4 = load float, ptr %a, align 4493  %sub3 = fsub float %3, %4494  %mul4 = fmul float %sub3, %div495  %5 = load float, ptr %min, align 4496  %sub5 = fsub float %5, %4497  %mul6 = fmul float %sub5, %div498  br label %if.end499 500if.end:                                           ; preds = %if.else, %if.then501  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]502  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]503 504  %6 = load float, ptr %max, align 4505  %7 = load float, ptr %a, align 4506  %sub6 = fsub float %6, %7507  %mul7 = fmul float %sub6, %div508  %8 = load float, ptr %min, align 4509  %sub8 = fsub float %8, %7510  %mul9 = fmul float %sub8, %div511 512  %add = fadd float %tmax.0, %tmin.0513  ret float %add514}515 516; Check that we do not hoist loads past stores from half diamond.517define float @noHoistInHalfDiamondPastStore(float %d, ptr %min, ptr %max, ptr %a) {518; CHECK-LABEL: @noHoistInHalfDiamondPastStore(519; CHECK-NEXT:  entry:520; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]521; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00522; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4523; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4524; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4525; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]526; CHECK:       if.then:527; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4528; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[A]], align 4529; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP2]], [[TMP3]]530; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]531; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[MIN]], align 4532; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP4]], [[TMP3]]533; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]534; CHECK-NEXT:    br label [[IF_END]]535; CHECK:       if.end:536; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL4]], [[IF_THEN]] ], [ [[TMP0]], [[ENTRY:%.*]] ]537; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL6]], [[IF_THEN]] ], [ [[TMP1]], [[ENTRY]] ]538; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]539; CHECK-NEXT:    ret float [[ADD]]540;541entry:542  %div = fdiv float 1.000000e+00, %d543  %cmp = fcmp oge float %div, 0.000000e+00544  %0 = load float, ptr %min, align 4545  %1 = load float, ptr %a, align 4546 547  ; Loads should not be hoisted above this store.548  store float 0.000000e+00, ptr @GlobalVar549 550  br i1 %cmp, label %if.then, label %if.end551 552if.then:553  ; There are no side effects on the if.then branch.554  %2 = load float, ptr %max, align 4555  %3 = load float, ptr %a, align 4556  %sub3 = fsub float %2, %3557  %mul4 = fmul float %sub3, %div558  %4 = load float, ptr %min, align 4559  %sub5 = fsub float %4, %3560  %mul6 = fmul float %sub5, %div561  br label %if.end562 563if.end:564  %tmax.0 = phi float [ %mul4, %if.then ], [ %0, %entry ]565  %tmin.0 = phi float [ %mul6, %if.then ], [ %1, %entry ]566 567  %add = fadd float %tmax.0, %tmin.0568  ret float %add569}570 571; Check that we do not hoist loads past a store in any branch of a diamond.572define float @noHoistInDiamondWithOneStore2(float %d, ptr %min, ptr %max, ptr %a) {573; CHECK-LABEL: @noHoistInDiamondWithOneStore2(574; CHECK-NEXT:  entry:575; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]576; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00577; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]578; CHECK:       if.then:579; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4580; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4581; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]582; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]583; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4584; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]585; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]586; CHECK-NEXT:    br label [[IF_END:%.*]]587; CHECK:       if.else:588; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4589; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4590; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4591; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]592; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]593; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4594; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]595; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]596; CHECK-NEXT:    br label [[IF_END]]597; CHECK:       if.end:598; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL6]], [[IF_ELSE]] ]599; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]600; CHECK-NEXT:    [[TMP6:%.*]] = load float, ptr [[MAX]], align 4601; CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr [[A]], align 4602; CHECK-NEXT:    [[SUB6:%.*]] = fsub float [[TMP6]], [[TMP7]]603; CHECK-NEXT:    [[MUL7:%.*]] = fmul float [[SUB6]], [[DIV]]604; CHECK-NEXT:    [[TMP8:%.*]] = load float, ptr [[MIN]], align 4605; CHECK-NEXT:    [[SUB8:%.*]] = fsub float [[TMP8]], [[TMP7]]606; CHECK-NEXT:    [[MUL9:%.*]] = fmul float [[SUB8]], [[DIV]]607; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]608; CHECK-NEXT:    ret float [[ADD]]609;610entry:611  %div = fdiv float 1.000000e+00, %d612  %cmp = fcmp oge float %div, 0.000000e+00613  br i1 %cmp, label %if.then, label %if.else614 615if.then:                                          ; preds = %entry616  ; There are no side effects on the if.then branch.617  %0 = load float, ptr %min, align 4618  %1 = load float, ptr %a, align 4619  %sub = fsub float %0, %1620  %mul = fmul float %sub, %div621  %2 = load float, ptr %max, align 4622  %sub1 = fsub float %2, %1623  %mul2 = fmul float %sub1, %div624  br label %if.end625 626if.else:                                          ; preds = %entry627  store float 0.000000e+00, ptr @GlobalVar628  %3 = load float, ptr %max, align 4629  %4 = load float, ptr %a, align 4630  %sub3 = fsub float %3, %4631  %mul4 = fmul float %sub3, %div632  %5 = load float, ptr %min, align 4633  %sub5 = fsub float %5, %4634  %mul6 = fmul float %sub5, %div635  br label %if.end636 637if.end:                                           ; preds = %if.else, %if.then638  %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]639  %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]640 641  %6 = load float, ptr %max, align 4642  %7 = load float, ptr %a, align 4643  %sub6 = fsub float %6, %7644  %mul7 = fmul float %sub6, %div645  %8 = load float, ptr %min, align 4646  %sub8 = fsub float %8, %7647  %mul9 = fmul float %sub8, %div648 649  %add = fadd float %tmax.0, %tmin.0650  ret float %add651}652 653; Check that we do not hoist loads outside a loop containing stores.654define float @noHoistInLoopsWithStores(float %d, ptr %min, ptr %max, ptr %a) {655; CHECK-LABEL: @noHoistInLoopsWithStores(656; CHECK-NEXT:  entry:657; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]658; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00659; CHECK-NEXT:    br i1 [[CMP]], label [[DO_BODY:%.*]], label [[IF_ELSE:%.*]]660; CHECK:       do.body:661; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4662; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4663; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4664; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]665; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]666; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4667; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]668; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]669; CHECK-NEXT:    br label [[WHILE_COND:%.*]]670; CHECK:       while.cond:671; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge float [[MUL2]], 0.000000e+00672; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END:%.*]], label [[DO_BODY]]673; CHECK:       if.else:674; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4675; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4676; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]677; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]678; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4679; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]680; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]681; CHECK-NEXT:    br label [[IF_END]]682; CHECK:       if.end:683; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[WHILE_COND]] ], [ [[MUL6]], [[IF_ELSE]] ]684; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[WHILE_COND]] ], [ [[MUL4]], [[IF_ELSE]] ]685; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]686; CHECK-NEXT:    ret float [[ADD]]687;688entry:689  %div = fdiv float 1.000000e+00, %d690  %cmp = fcmp oge float %div, 0.000000e+00691  br i1 %cmp, label %do.body, label %if.else692 693do.body:694  %0 = load float, ptr %min, align 4695  %1 = load float, ptr %a, align 4696 697  ; It is unsafe to hoist the loads outside the loop because of the store.698  store float 0.000000e+00, ptr @GlobalVar699 700  %sub = fsub float %0, %1701  %mul = fmul float %sub, %div702  %2 = load float, ptr %max, align 4703  %sub1 = fsub float %2, %1704  %mul2 = fmul float %sub1, %div705  br label %while.cond706 707while.cond:708  %cmp1 = fcmp oge float %mul2, 0.000000e+00709  br i1 %cmp1, label %if.end, label %do.body710 711if.else:712  %3 = load float, ptr %max, align 4713  %4 = load float, ptr %a, align 4714  %sub3 = fsub float %3, %4715  %mul4 = fmul float %sub3, %div716  %5 = load float, ptr %min, align 4717  %sub5 = fsub float %5, %4718  %mul6 = fmul float %sub5, %div719  br label %if.end720 721if.end:722  %tmax.0 = phi float [ %mul2, %while.cond ], [ %mul6, %if.else ]723  %tmin.0 = phi float [ %mul, %while.cond ], [ %mul4, %if.else ]724 725  %add = fadd float %tmax.0, %tmin.0726  ret float %add727}728 729; Check that we hoist stores: all the instructions from the then branch730; should be hoisted.731 732%struct.foo = type { ptr }733 734define void @hoistStores(ptr %s, ptr %coord, i1 zeroext %delta) {735; CHECK-LABEL: @hoistStores(736; CHECK-NEXT:  entry:737; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[DELTA:%.*]] to i8738; CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[FROMBOOL]] to i1739; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[S:%.*]], i32 0, i32 0740; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8741; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0742; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1743; CHECK-NEXT:    store ptr [[TMP3]], ptr [[TMP2]], align 8744; CHECK-NEXT:    [[TMP4:%.*]] = load i16, ptr [[TMP1]], align 2745; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[COORD:%.*]], align 4746; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[TMP4]] to i32747; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP5]], [[CONV]]748; CHECK-NEXT:    store i32 [[ADD]], ptr [[COORD]], align 4749; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]750; CHECK:       if.then:751; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0752; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1753; CHECK-NEXT:    br label [[IF_END:%.*]]754; CHECK:       if.else:755; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0756; CHECK-NEXT:    [[INCDEC_PTR2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1757; CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[P1]], align 8758; CHECK-NEXT:    [[INCDEC_PTR6:%.*]] = getelementptr inbounds i16, ptr [[TMP6]], i32 1759; CHECK-NEXT:    store ptr [[INCDEC_PTR6]], ptr [[P1]], align 8760; CHECK-NEXT:    [[TMP7:%.*]] = load i16, ptr [[TMP6]], align 2761; CHECK-NEXT:    [[CONV7:%.*]] = zext i16 [[TMP7]] to i32762; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV7]], 8763; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[COORD]], align 4764; CHECK-NEXT:    [[ADD8:%.*]] = add i32 [[TMP8]], [[SHL]]765; CHECK-NEXT:    store i32 [[ADD8]], ptr [[COORD]], align 4766; CHECK-NEXT:    br label [[IF_END]]767; CHECK:       if.end:768; CHECK-NEXT:    ret void769;770entry:771  %frombool = zext i1 %delta to i8772  %tobool = trunc i8 %frombool to i1773  br i1 %tobool, label %if.then, label %if.else774 775if.then:                                          ; preds = %entry776  %p = getelementptr inbounds %struct.foo, ptr %s, i32 0, i32 0777  %0 = load ptr, ptr %p, align 8778  %incdec.ptr = getelementptr inbounds i16, ptr %0, i32 1779  store ptr %incdec.ptr, ptr %p, align 8780  %1 = load i16, ptr %0, align 2781  %conv = zext i16 %1 to i32782  %2 = load i32, ptr %coord, align 4783  %add = add i32 %2, %conv784  store i32 %add, ptr %coord, align 4785  br label %if.end786 787if.else:                                          ; preds = %entry788  %p1 = getelementptr inbounds %struct.foo, ptr %s, i32 0, i32 0789  %3 = load ptr, ptr %p1, align 8790  %incdec.ptr2 = getelementptr inbounds i16, ptr %3, i32 1791  store ptr %incdec.ptr2, ptr %p1, align 8792  %4 = load i16, ptr %3, align 2793  %conv3 = zext i16 %4 to i32794  %5 = load i32, ptr %coord, align 4795  %add4 = add i32 %5, %conv3796  store i32 %add4, ptr %coord, align 4797  %6 = load ptr, ptr %p1, align 8798  %incdec.ptr6 = getelementptr inbounds i16, ptr %6, i32 1799  store ptr %incdec.ptr6, ptr %p1, align 8800  %7 = load i16, ptr %6, align 2801  %conv7 = zext i16 %7 to i32802  %shl = shl i32 %conv7, 8803  %8 = load i32, ptr %coord, align 4804  %add8 = add i32 %8, %shl805  store i32 %add8, ptr %coord, align 4806  br label %if.end807 808if.end:                                           ; preds = %if.else, %if.then809  ret void810}811 812define i32 @mergeAlignments(i1 %b, ptr %y) {813; CHECK-LABEL: @mergeAlignments(814; CHECK-NEXT:  entry:815; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[Y:%.*]], align 1816; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]817; CHECK:       if.then:818; CHECK-NEXT:    br label [[RETURN:%.*]]819; CHECK:       if.end:820; CHECK-NEXT:    br label [[RETURN]]821; CHECK:       return:822; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[L1]], [[IF_THEN]] ], [ [[L1]], [[IF_END]] ]823; CHECK-NEXT:    ret i32 [[RETVAL_0]]824;825entry:826  br i1 %b, label %if.then, label %if.end827 828if.then:                                          ; preds = %entry829  %l1 = load i32, ptr %y, align 4830  br label %return831 832if.end:                                           ; preds = %entry833  %l2 = load i32, ptr %y, align 1834  br label %return835 836return:                                           ; preds = %if.end, %if.then837  %retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ]838  ret i32 %retval.0839}840 841declare i8 @pr30991_f() nounwind readonly842declare void @pr30991_f1(i8)843define i8 @pr30991(ptr %sp, ptr %word, i1 %b1, i1 %b2) {844; CHECK-LABEL: @pr30991(845; CHECK-NEXT:  entry:846; CHECK-NEXT:    [[R0:%.*]] = load i8, ptr [[WORD:%.*]], align 1847; CHECK-NEXT:    br i1 [[B1:%.*]], label [[A:%.*]], label [[B:%.*]]848; CHECK:       a:849; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr i8, ptr [[SP:%.*]], i32 1850; CHECK-NEXT:    [[RR0:%.*]] = call i8 @pr30991_f() #[[ATTR0:[0-9]+]]851; CHECK-NEXT:    call void @pr30991_f1(i8 [[R0]])852; CHECK-NEXT:    ret i8 [[RR0]]853; CHECK:       b:854; CHECK-NEXT:    br i1 [[B2:%.*]], label [[C:%.*]], label [[X:%.*]]855; CHECK:       c:856; CHECK-NEXT:    [[INCDEC_PTR115:%.*]] = getelementptr i8, ptr [[SP]], i32 1857; CHECK-NEXT:    [[RR1:%.*]] = call i8 @pr30991_f() #[[ATTR0]]858; CHECK-NEXT:    call void @pr30991_f1(i8 [[R0]])859; CHECK-NEXT:    ret i8 [[RR1]]860; CHECK:       x:861; CHECK-NEXT:    ret i8 [[R0]]862;863entry:864  br i1 %b1, label %a, label %b865 866a:867  %r0 = load i8, ptr %word, align 1868  %incdec.ptr = getelementptr i8, ptr %sp, i32 1869  %rr0 = call i8 @pr30991_f() nounwind readonly870  call void @pr30991_f1(i8 %r0)871  ret i8 %rr0872 873b:874  br i1 %b2, label %c, label %x875 876c:877  %r1 = load i8, ptr %word, align 1878  %incdec.ptr115 = getelementptr i8, ptr %sp, i32 1879  %rr1 = call i8 @pr30991_f() nounwind readonly880  call void @pr30991_f1(i8 %r1)881  ret i8 %rr1882 883x:884  %r2 = load i8, ptr %word, align 1885  ret i8 %r2886}887