1 ; RUN: opt -gvn-hoist -S < %s | FileCheck %s 2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 target triple = "x86_64-unknown-linux-gnu" 4 5 @GlobalVar = internal global float 1.000000e+00 6 7 ; Check that all scalar expressions are hoisted. 8 ; 9 ; CHECK-LABEL: @scalarsHoisting 10 ; CHECK: fsub 11 ; CHECK: fmul 12 ; CHECK: fsub 13 ; CHECK: fmul 14 ; CHECK-NOT: fmul 15 ; CHECK-NOT: fsub 16 define float @scalarsHoisting(float %d, float %min, float %max, float %a) { 17 entry: 18 %div = fdiv float 1.000000e+00, %d 19 %cmp = fcmp oge float %div, 0.000000e+00 20 br i1 %cmp, label %if.then, label %if.else 21 22 if.then: ; preds = %entry 23 %sub = fsub float %min, %a 24 %mul = fmul float %sub, %div 25 %sub1 = fsub float %max, %a 26 %mul2 = fmul float %sub1, %div 27 br label %if.end 28 29 if.else: ; preds = %entry 30 %sub3 = fsub float %max, %a 31 %mul4 = fmul float %sub3, %div 32 %sub5 = fsub float %min, %a 33 %mul6 = fmul float %sub5, %div 34 br label %if.end 35 36 if.end: ; preds = %if.else, %if.then 37 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 38 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 39 %add = fadd float %tmax.0, %tmin.0 40 ret float %add 41 } 42 43 ; Check that all loads and scalars depending on the loads are hoisted. 44 ; Check that getelementptr computation gets hoisted before the load. 45 ; 46 ; CHECK-LABEL: @readsAndScalarsHoisting 47 ; CHECK: load 48 ; CHECK: load 49 ; CHECK: load 50 ; CHECK: fsub 51 ; CHECK: fmul 52 ; CHECK: fsub 53 ; CHECK: fmul 54 ; CHECK-NOT: load 55 ; CHECK-NOT: fmul 56 ; CHECK-NOT: fsub 57 define float @readsAndScalarsHoisting(float %d, float* %min, float* %max, float* %a) { 58 entry: 59 %div = fdiv float 1.000000e+00, %d 60 %cmp = fcmp oge float %div, 0.000000e+00 61 br i1 %cmp, label %if.then, label %if.else 62 63 if.then: ; preds = %entry 64 %A = getelementptr float, float* %min, i32 1 65 %0 = load float, float* %A, align 4 66 %1 = load float, float* %a, align 4 67 %sub = fsub float %0, %1 68 %mul = fmul float %sub, %div 69 %2 = load float, float* %max, align 4 70 %sub1 = fsub float %2, %1 71 %mul2 = fmul float %sub1, %div 72 br label %if.end 73 74 if.else: ; preds = %entry 75 %3 = load float, float* %max, align 4 76 %4 = load float, float* %a, align 4 77 %sub3 = fsub float %3, %4 78 %mul4 = fmul float %sub3, %div 79 %B = getelementptr float, float* %min, i32 1 80 %5 = load float, float* %B, align 4 81 %sub5 = fsub float %5, %4 82 %mul6 = fmul float %sub5, %div 83 br label %if.end 84 85 if.end: ; preds = %if.else, %if.then 86 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 87 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 88 %add = fadd float %tmax.0, %tmin.0 89 ret float %add 90 } 91 92 ; Check that we do not hoist loads after a store: the first two loads will be 93 ; hoisted, and then the third load will not be hoisted. 94 ; 95 ; CHECK-LABEL: @readsAndWrites 96 ; CHECK: load 97 ; CHECK: load 98 ; CHECK: fsub 99 ; CHECK: fmul 100 ; CHECK: store 101 ; CHECK: load 102 ; CHECK: fsub 103 ; CHECK: fmul 104 ; CHECK: load 105 ; CHECK: fsub 106 ; CHECK: fmul 107 ; CHECK-NOT: load 108 ; CHECK-NOT: fmul 109 ; CHECK-NOT: fsub 110 define float @readsAndWrites(float %d, float* %min, float* %max, float* %a) { 111 entry: 112 %div = fdiv float 1.000000e+00, %d 113 %cmp = fcmp oge float %div, 0.000000e+00 114 br i1 %cmp, label %if.then, label %if.else 115 116 if.then: ; preds = %entry 117 %0 = load float, float* %min, align 4 118 %1 = load float, float* %a, align 4 119 store float %0, float* @GlobalVar 120 %sub = fsub float %0, %1 121 %mul = fmul float %sub, %div 122 %2 = load float, float* %max, align 4 123 %sub1 = fsub float %2, %1 124 %mul2 = fmul float %sub1, %div 125 br label %if.end 126 127 if.else: ; preds = %entry 128 %3 = load float, float* %max, align 4 129 %4 = load float, float* %a, align 4 130 %sub3 = fsub float %3, %4 131 %mul4 = fmul float %sub3, %div 132 %5 = load float, float* %min, align 4 133 %sub5 = fsub float %5, %4 134 %mul6 = fmul float %sub5, %div 135 br label %if.end 136 137 if.end: ; preds = %if.else, %if.then 138 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 139 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 140 %add = fadd float %tmax.0, %tmin.0 141 ret float %add 142 } 143 144 ; Check that we do hoist loads when the store is above the insertion point. 145 ; 146 ; CHECK-LABEL: @readsAndWriteAboveInsertPt 147 ; CHECK: load 148 ; CHECK: load 149 ; CHECK: load 150 ; CHECK: fsub 151 ; CHECK: fmul 152 ; CHECK: fsub 153 ; CHECK: fmul 154 ; CHECK-NOT: load 155 ; CHECK-NOT: fmul 156 ; CHECK-NOT: fsub 157 define float @readsAndWriteAboveInsertPt(float %d, float* %min, float* %max, float* %a) { 158 entry: 159 %div = fdiv float 1.000000e+00, %d 160 store float 0.000000e+00, float* @GlobalVar 161 %cmp = fcmp oge float %div, 0.000000e+00 162 br i1 %cmp, label %if.then, label %if.else 163 164 if.then: ; preds = %entry 165 %0 = load float, float* %min, align 4 166 %1 = load float, float* %a, align 4 167 %sub = fsub float %0, %1 168 %mul = fmul float %sub, %div 169 %2 = load float, float* %max, align 4 170 %sub1 = fsub float %2, %1 171 %mul2 = fmul float %sub1, %div 172 br label %if.end 173 174 if.else: ; preds = %entry 175 %3 = load float, float* %max, align 4 176 %4 = load float, float* %a, align 4 177 %sub3 = fsub float %3, %4 178 %mul4 = fmul float %sub3, %div 179 %5 = load float, float* %min, align 4 180 %sub5 = fsub float %5, %4 181 %mul6 = fmul float %sub5, %div 182 br label %if.end 183 184 if.end: ; preds = %if.else, %if.then 185 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 186 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 187 %add = fadd float %tmax.0, %tmin.0 188 ret float %add 189 } 190 191 ; Check that dependent expressions are hoisted. 192 ; CHECK-LABEL: @dependentScalarsHoisting 193 ; CHECK: fsub 194 ; CHECK: fadd 195 ; CHECK: fdiv 196 ; CHECK: fmul 197 ; CHECK-NOT: fsub 198 ; CHECK-NOT: fadd 199 ; CHECK-NOT: fdiv 200 ; CHECK-NOT: fmul 201 define float @dependentScalarsHoisting(float %a, float %b, i1 %c) { 202 entry: 203 br i1 %c, label %if.then, label %if.else 204 205 if.then: 206 %d = fsub float %b, %a 207 %e = fadd float %d, %a 208 %f = fdiv float %e, %a 209 %g = fmul float %f, %a 210 br label %if.end 211 212 if.else: 213 %h = fsub float %b, %a 214 %i = fadd float %h, %a 215 %j = fdiv float %i, %a 216 %k = fmul float %j, %a 217 br label %if.end 218 219 if.end: 220 %r = phi float [ %g, %if.then ], [ %k, %if.else ] 221 ret float %r 222 } 223 224 ; Check that all independent expressions are hoisted. 225 ; CHECK-LABEL: @independentScalarsHoisting 226 ; CHECK: fsub 227 ; CHECK: fdiv 228 ; CHECK: fmul 229 ; CHECK: fadd 230 ; CHECK-NOT: fsub 231 ; CHECK-NOT: fdiv 232 ; CHECK-NOT: fmul 233 define float @independentScalarsHoisting(float %a, float %b, i1 %c) { 234 entry: 235 br i1 %c, label %if.then, label %if.else 236 237 if.then: 238 %d = fadd float %b, %a 239 %e = fsub float %b, %a 240 %f = fdiv float %b, %a 241 %g = fmul float %b, %a 242 br label %if.end 243 244 if.else: 245 %i = fadd float %b, %a 246 %h = fsub float %b, %a 247 %j = fdiv float %b, %a 248 %k = fmul float %b, %a 249 br label %if.end 250 251 if.end: 252 %p = phi float [ %d, %if.then ], [ %i, %if.else ] 253 %q = phi float [ %e, %if.then ], [ %h, %if.else ] 254 %r = phi float [ %f, %if.then ], [ %j, %if.else ] 255 %s = phi float [ %g, %if.then ], [ %k, %if.else ] 256 %t = fadd float %p, %q 257 %u = fadd float %r, %s 258 %v = fadd float %t, %u 259 ret float %v 260 } 261 262 ; Check that we hoist load and scalar expressions in triangles. 263 ; CHECK-LABEL: @triangleHoisting 264 ; CHECK: load 265 ; CHECK: load 266 ; CHECK: load 267 ; CHECK: fsub 268 ; CHECK: fmul 269 ; CHECK: fsub 270 ; CHECK: fmul 271 ; CHECK-NOT: load 272 ; CHECK-NOT: fmul 273 ; CHECK-NOT: fsub 274 define float @triangleHoisting(float %d, float* %min, float* %max, float* %a) { 275 entry: 276 %div = fdiv float 1.000000e+00, %d 277 %cmp = fcmp oge float %div, 0.000000e+00 278 br i1 %cmp, label %if.then, label %if.end 279 280 if.then: ; preds = %entry 281 %0 = load float, float* %min, align 4 282 %1 = load float, float* %a, align 4 283 %sub = fsub float %0, %1 284 %mul = fmul float %sub, %div 285 %2 = load float, float* %max, align 4 286 %sub1 = fsub float %2, %1 287 %mul2 = fmul float %sub1, %div 288 br label %if.end 289 290 if.end: ; preds = %entry 291 %p1 = phi float [ %mul2, %if.then ], [ 0.000000e+00, %entry ] 292 %p2 = phi float [ %mul, %if.then ], [ 0.000000e+00, %entry ] 293 %3 = load float, float* %max, align 4 294 %4 = load float, float* %a, align 4 295 %sub3 = fsub float %3, %4 296 %mul4 = fmul float %sub3, %div 297 %5 = load float, float* %min, align 4 298 %sub5 = fsub float %5, %4 299 %mul6 = fmul float %sub5, %div 300 301 %x = fadd float %p1, %mul6 302 %y = fadd float %p2, %mul4 303 %z = fadd float %x, %y 304 ret float %z 305 } 306 307 ; Check that we do not hoist loads past stores within a same basic block. 308 ; CHECK-LABEL: @noHoistInSingleBBWithStore 309 ; CHECK: load 310 ; CHECK: store 311 ; CHECK: load 312 ; CHECK: store 313 define i32 @noHoistInSingleBBWithStore() { 314 entry: 315 %D = alloca i32, align 4 316 %0 = bitcast i32* %D to i8* 317 %bf = load i8, i8* %0, align 4 318 %bf.clear = and i8 %bf, -3 319 store i8 %bf.clear, i8* %0, align 4 320 %bf1 = load i8, i8* %0, align 4 321 %bf.clear1 = and i8 %bf1, 1 322 store i8 %bf.clear1, i8* %0, align 4 323 ret i32 0 324 } 325 326 ; Check that we do not hoist loads past calls within a same basic block. 327 ; CHECK-LABEL: @noHoistInSingleBBWithCall 328 ; CHECK: load 329 ; CHECK: call 330 ; CHECK: load 331 declare void @foo() 332 define i32 @noHoistInSingleBBWithCall() { 333 entry: 334 %D = alloca i32, align 4 335 %0 = bitcast i32* %D to i8* 336 %bf = load i8, i8* %0, align 4 337 %bf.clear = and i8 %bf, -3 338 call void @foo() 339 %bf1 = load i8, i8* %0, align 4 340 %bf.clear1 = and i8 %bf1, 1 341 ret i32 0 342 } 343 344 ; Check that we do not hoist loads past stores in any branch of a diamond. 345 ; CHECK-LABEL: @noHoistInDiamondWithOneStore1 346 ; CHECK: fdiv 347 ; CHECK: fcmp 348 ; CHECK: br 349 define float @noHoistInDiamondWithOneStore1(float %d, float* %min, float* %max, float* %a) { 350 entry: 351 %div = fdiv float 1.000000e+00, %d 352 %cmp = fcmp oge float %div, 0.000000e+00 353 br i1 %cmp, label %if.then, label %if.else 354 355 if.then: ; preds = %entry 356 store float 0.000000e+00, float* @GlobalVar 357 %0 = load float, float* %min, align 4 358 %1 = load float, float* %a, align 4 359 %sub = fsub float %0, %1 360 %mul = fmul float %sub, %div 361 %2 = load float, float* %max, align 4 362 %sub1 = fsub float %2, %1 363 %mul2 = fmul float %sub1, %div 364 br label %if.end 365 366 if.else: ; preds = %entry 367 ; There are no side effects on the if.else branch. 368 %3 = load float, float* %max, align 4 369 %4 = load float, float* %a, align 4 370 %sub3 = fsub float %3, %4 371 %mul4 = fmul float %sub3, %div 372 %5 = load float, float* %min, align 4 373 %sub5 = fsub float %5, %4 374 %mul6 = fmul float %sub5, %div 375 br label %if.end 376 377 if.end: ; preds = %if.else, %if.then 378 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 379 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 380 381 %6 = load float, float* %max, align 4 382 %7 = load float, float* %a, align 4 383 %sub6 = fsub float %6, %7 384 %mul7 = fmul float %sub6, %div 385 %8 = load float, float* %min, align 4 386 %sub8 = fsub float %8, %7 387 %mul9 = fmul float %sub8, %div 388 389 %add = fadd float %tmax.0, %tmin.0 390 ret float %add 391 } 392 393 ; Check that we do not hoist loads past stores from half diamond. 394 ; CHECK-LABEL: @noHoistInHalfDiamondPastStore 395 ; CHECK: load 396 ; CHECK-NEXT: load 397 ; CHECK-NEXT: store 398 ; CHECK-NEXT: br 399 ; CHECK: load 400 ; CHECK: load 401 ; CHECK: load 402 ; CHECK: br 403 define float @noHoistInHalfDiamondPastStore(float %d, float* %min, float* %max, float* %a) { 404 entry: 405 %div = fdiv float 1.000000e+00, %d 406 %cmp = fcmp oge float %div, 0.000000e+00 407 %0 = load float, float* %min, align 4 408 %1 = load float, float* %a, align 4 409 410 ; Loads should not be hoisted above this store. 411 store float 0.000000e+00, float* @GlobalVar 412 413 br i1 %cmp, label %if.then, label %if.end 414 415 if.then: 416 ; There are no side effects on the if.then branch. 417 %2 = load float, float* %max, align 4 418 %3 = load float, float* %a, align 4 419 %sub3 = fsub float %2, %3 420 %mul4 = fmul float %sub3, %div 421 %4 = load float, float* %min, align 4 422 %sub5 = fsub float %4, %3 423 %mul6 = fmul float %sub5, %div 424 br label %if.end 425 426 if.end: 427 %tmax.0 = phi float [ %mul4, %if.then ], [ %0, %entry ] 428 %tmin.0 = phi float [ %mul6, %if.then ], [ %1, %entry ] 429 430 %add = fadd float %tmax.0, %tmin.0 431 ret float %add 432 } 433 434 ; Check that we do not hoist loads past a store in any branch of a diamond. 435 ; CHECK-LABEL: @noHoistInDiamondWithOneStore2 436 ; CHECK: fdiv 437 ; CHECK: fcmp 438 ; CHECK: br 439 define float @noHoistInDiamondWithOneStore2(float %d, float* %min, float* %max, float* %a) { 440 entry: 441 %div = fdiv float 1.000000e+00, %d 442 %cmp = fcmp oge float %div, 0.000000e+00 443 br i1 %cmp, label %if.then, label %if.else 444 445 if.then: ; preds = %entry 446 ; There are no side effects on the if.then branch. 447 %0 = load float, float* %min, align 4 448 %1 = load float, float* %a, align 4 449 %sub = fsub float %0, %1 450 %mul = fmul float %sub, %div 451 %2 = load float, float* %max, align 4 452 %sub1 = fsub float %2, %1 453 %mul2 = fmul float %sub1, %div 454 br label %if.end 455 456 if.else: ; preds = %entry 457 store float 0.000000e+00, float* @GlobalVar 458 %3 = load float, float* %max, align 4 459 %4 = load float, float* %a, align 4 460 %sub3 = fsub float %3, %4 461 %mul4 = fmul float %sub3, %div 462 %5 = load float, float* %min, align 4 463 %sub5 = fsub float %5, %4 464 %mul6 = fmul float %sub5, %div 465 br label %if.end 466 467 if.end: ; preds = %if.else, %if.then 468 %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ] 469 %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ] 470 471 %6 = load float, float* %max, align 4 472 %7 = load float, float* %a, align 4 473 %sub6 = fsub float %6, %7 474 %mul7 = fmul float %sub6, %div 475 %8 = load float, float* %min, align 4 476 %sub8 = fsub float %8, %7 477 %mul9 = fmul float %sub8, %div 478 479 %add = fadd float %tmax.0, %tmin.0 480 ret float %add 481 } 482 483 ; Check that we do not hoist loads outside a loop containing stores. 484 ; CHECK-LABEL: @noHoistInLoopsWithStores 485 ; CHECK: fdiv 486 ; CHECK: fcmp 487 ; CHECK: br 488 define float @noHoistInLoopsWithStores(float %d, float* %min, float* %max, float* %a) { 489 entry: 490 %div = fdiv float 1.000000e+00, %d 491 %cmp = fcmp oge float %div, 0.000000e+00 492 br i1 %cmp, label %do.body, label %if.else 493 494 do.body: 495 %0 = load float, float* %min, align 4 496 %1 = load float, float* %a, align 4 497 498 ; It is unsafe to hoist the loads outside the loop because of the store. 499 store float 0.000000e+00, float* @GlobalVar 500 501 %sub = fsub float %0, %1 502 %mul = fmul float %sub, %div 503 %2 = load float, float* %max, align 4 504 %sub1 = fsub float %2, %1 505 %mul2 = fmul float %sub1, %div 506 br label %while.cond 507 508 while.cond: 509 %cmp1 = fcmp oge float %mul2, 0.000000e+00 510 br i1 %cmp1, label %if.end, label %do.body 511 512 if.else: 513 %3 = load float, float* %max, align 4 514 %4 = load float, float* %a, align 4 515 %sub3 = fsub float %3, %4 516 %mul4 = fmul float %sub3, %div 517 %5 = load float, float* %min, align 4 518 %sub5 = fsub float %5, %4 519 %mul6 = fmul float %sub5, %div 520 br label %if.end 521 522 if.end: 523 %tmax.0 = phi float [ %mul2, %while.cond ], [ %mul6, %if.else ] 524 %tmin.0 = phi float [ %mul, %while.cond ], [ %mul4, %if.else ] 525 526 %add = fadd float %tmax.0, %tmin.0 527 ret float %add 528 } 529 530 ; Check that we hoist stores: all the instructions from the then branch 531 ; should be hoisted. 532 ; CHECK-LABEL: @hoistStores 533 ; CHECK: zext 534 ; CHECK-NEXT: trunc 535 ; CHECK-NEXT: getelementptr 536 ; CHECK-NEXT: load 537 ; CHECK-NEXT: getelementptr 538 ; CHECK-NEXT: getelementptr 539 ; CHECK-NEXT: store 540 ; CHECK-NEXT: load 541 ; CHECK-NEXT: load 542 ; CHECK-NEXT: zext 543 ; CHECK-NEXT: add 544 ; CHECK-NEXT: store 545 ; CHECK-NEXT: br 546 ; CHECK: if.then 547 ; CHECK: br 548 549 %struct.foo = type { i16* } 550 551 define void @hoistStores(%struct.foo* %s, i32* %coord, i1 zeroext %delta) { 552 entry: 553 %frombool = zext i1 %delta to i8 554 %tobool = trunc i8 %frombool to i1 555 br i1 %tobool, label %if.then, label %if.else 556 557 if.then: ; preds = %entry 558 %p = getelementptr inbounds %struct.foo, %struct.foo* %s, i32 0, i32 0 559 %0 = load i16*, i16** %p, align 8 560 %incdec.ptr = getelementptr inbounds i16, i16* %0, i32 1 561 store i16* %incdec.ptr, i16** %p, align 8 562 %1 = load i16, i16* %0, align 2 563 %conv = zext i16 %1 to i32 564 %2 = load i32, i32* %coord, align 4 565 %add = add i32 %2, %conv 566 store i32 %add, i32* %coord, align 4 567 br label %if.end 568 569 if.else: ; preds = %entry 570 %p1 = getelementptr inbounds %struct.foo, %struct.foo* %s, i32 0, i32 0 571 %3 = load i16*, i16** %p1, align 8 572 %incdec.ptr2 = getelementptr inbounds i16, i16* %3, i32 1 573 store i16* %incdec.ptr2, i16** %p1, align 8 574 %4 = load i16, i16* %3, align 2 575 %conv3 = zext i16 %4 to i32 576 %5 = load i32, i32* %coord, align 4 577 %add4 = add i32 %5, %conv3 578 store i32 %add4, i32* %coord, align 4 579 %6 = load i16*, i16** %p1, align 8 580 %incdec.ptr6 = getelementptr inbounds i16, i16* %6, i32 1 581 store i16* %incdec.ptr6, i16** %p1, align 8 582 %7 = load i16, i16* %6, align 2 583 %conv7 = zext i16 %7 to i32 584 %shl = shl i32 %conv7, 8 585 %8 = load i32, i32* %coord, align 4 586 %add8 = add i32 %8, %shl 587 store i32 %add8, i32* %coord, align 4 588 br label %if.end 589 590 if.end: ; preds = %if.else, %if.then 591 ret void 592 } 593 594 define i32 @mergeAlignments(i1 %b, i32* %y) { 595 entry: 596 br i1 %b, label %if.then, label %if.end 597 598 if.then: ; preds = %entry 599 %l1 = load i32, i32* %y, align 4 600 br label %return 601 602 if.end: ; preds = %entry 603 %l2 = load i32, i32* %y, align 1 604 br label %return 605 606 return: ; preds = %if.end, %if.then 607 %retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ] 608 ret i32 %retval.0 609 } 610 ; CHECK-LABEL: define i32 @mergeAlignments( 611 ; CHECK: %[[load:.*]] = load i32, i32* %y, align 1 612 ; CHECK: %[[phi:.*]] = phi i32 [ %[[load]], %{{.*}} ], [ %[[load]], %{{.*}} ] 613 ; CHECK: i32 %[[phi]] 614 615 616 declare i8 @pr30991_f() nounwind readonly 617 declare void @pr30991_f1(i8) 618 define i8 @pr30991(i8* %sp, i8* %word, i1 %b1, i1 %b2) { 619 entry: 620 br i1 %b1, label %a, label %b 621 622 a: 623 %r0 = load i8, i8* %word, align 1 624 %incdec.ptr = getelementptr i8, i8* %sp, i32 1 625 %rr0 = call i8 @pr30991_f() nounwind readonly 626 call void @pr30991_f1(i8 %r0) 627 ret i8 %rr0 628 629 b: 630 br i1 %b2, label %c, label %x 631 632 c: 633 %r1 = load i8, i8* %word, align 1 634 %incdec.ptr115 = getelementptr i8, i8* %sp, i32 1 635 %rr1 = call i8 @pr30991_f() nounwind readonly 636 call void @pr30991_f1(i8 %r1) 637 ret i8 %rr1 638 639 x: 640 %r2 = load i8, i8* %word, align 1 641 ret i8 %r2 642 } 643 644 ; CHECK-LABEL: define i8 @pr30991 645 ; CHECK: %r0 = load i8, i8* %word, align 1 646 ; CHECK-NEXT: br i1 %b1, label %a, label %b 647