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