| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=true -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-YES |
| ; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=false -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO |
| target datalayout = |
| "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" |
| target triple = "x86_64-unknown-linux-gnu" |
| |
| ; Can we sink for different base if there is no phi for base? |
| define i32 @test1(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test1( |
| ; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test1( |
| ; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Can we sink for different base if there is phi for base? |
| define i32 @test2(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-LABEL: define i32 @test2( |
| ; CHECK-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %b = phi ptr [%b1, %entry], [%b2, %if.then] |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Can we sink for different base if there is phi for base but not valid one? |
| define i32 @test3(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test3( |
| ; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test3( |
| ; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %b = phi ptr [%b2, %entry], [%b1, %if.then] |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Can we sink for different base if both addresses are in the same block? |
| define i32 @test4(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test4( |
| ; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test4( |
| ; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Can we sink for different base if there is phi for base? |
| ; Both addresses are in the same block. |
| define i32 @test5(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-LABEL: define i32 @test5( |
| ; CHECK-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %b = phi ptr [%b1, %entry], [%b2, %if.then] |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Can we sink for different base if there is phi for base but not valid one? |
| ; Both addresses are in the same block. |
| define i32 @test6(i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test6( |
| ; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test6( |
| ; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %b = phi ptr [%b2, %entry], [%b1, %if.then] |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; case with a loop. No phi node. |
| define i32 @test7(i32 %N, i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test7( |
| ; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-YES: [[LOOP]]: |
| ; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ] |
| ; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[FALLTHROUGH]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ] |
| ; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-YES: [[EXIT]]: |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test7( |
| ; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-NO: [[LOOP]]: |
| ; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ] |
| ; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-NO: [[EXIT]]: |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] |
| %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%c3, %loop], [%a2, %if.then] |
| %v = load volatile i32, ptr %c, align 4 |
| %iv.inc = add i32 %iv, 1 |
| %cmp = icmp slt i32 %iv.inc, %N |
| br i1 %cmp, label %loop, label %exit |
| |
| exit: |
| ret i32 %v |
| } |
| |
| ; case with a loop. There is phi node. |
| define i32 @test8(i32 %N, i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-LABEL: define i32 @test8( |
| ; CHECK-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NEXT: br label %[[LOOP:.*]] |
| ; CHECK: [[LOOP]]: |
| ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ] |
| ; CHECK-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: [[B]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] |
| %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] |
| %b3 = phi ptr [%b1, %entry], [%b, %fallthrough] |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%c3, %loop], [%a2, %if.then] |
| %b = phi ptr [%b3, %loop], [%b2, %if.then] |
| %v = load volatile i32, ptr %c, align 4 |
| %iv.inc = add i32 %iv, 1 |
| %cmp = icmp slt i32 %iv.inc, %N |
| br i1 %cmp, label %loop, label %exit |
| |
| exit: |
| ret i32 %v |
| } |
| |
| ; case with a loop. There is phi node but it does not fit. |
| define i32 @test9(i32 %N, i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test9( |
| ; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-YES: [[LOOP]]: |
| ; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ] |
| ; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[FALLTHROUGH]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-YES-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[FALLTHROUGH]] ] |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ] |
| ; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-YES: [[EXIT]]: |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test9( |
| ; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-NO: [[LOOP]]: |
| ; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ] |
| ; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ] |
| ; CHECK-NO-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[FALLTHROUGH]] ] |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-NO: [[EXIT]]: |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] |
| %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] |
| %b3 = phi ptr [%b1, %entry], [%b2, %fallthrough] |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%c3, %loop], [%a2, %if.then] |
| %b = phi ptr [%b3, %loop], [%b2, %if.then] |
| %v = load volatile i32, ptr %c, align 4 |
| %iv.inc = add i32 %iv, 1 |
| %cmp = icmp slt i32 %iv.inc, %N |
| br i1 %cmp, label %loop, label %exit |
| |
| exit: |
| ret i32 %v |
| } |
| |
| ; Case through a loop. No phi node. |
| define i32 @test10(i32 %N, i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test10( |
| ; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-YES: [[LOOP]]: |
| ; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ] |
| ; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-YES: [[EXIT]]: |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test10( |
| ; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-NO: [[LOOP]]: |
| ; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ] |
| ; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-NO: [[EXIT]]: |
| ; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop] |
| %iv.inc = add i32 %iv, 1 |
| %cmp = icmp slt i32 %iv.inc, %N |
| br i1 %cmp, label %loop, label %exit |
| |
| exit: |
| %v = load volatile i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Case through a loop. There is a phi. |
| define i32 @test11(i32 %N, i1 %cond, ptr %b1, ptr %b2) { |
| ; CHECK-LABEL: define i32 @test11( |
| ; CHECK-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: br label %[[LOOP:.*]] |
| ; CHECK: [[LOOP]]: |
| ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ] |
| ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%a1, %entry], [%a2, %if.then] |
| %b = phi ptr [%b1, %entry], [%b2, %if.then] |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop] |
| %iv.inc = add i32 %iv, 1 |
| %cmp = icmp slt i32 %iv.inc, %N |
| br i1 %cmp, label %loop, label %exit |
| |
| exit: |
| %v = load volatile i32, ptr %c, align 4 |
| ret i32 %v |
| } |
| |
| ; Complex case with address value from previous iteration. |
| define i32 @test12(i32 %N, i1 %cond, ptr %b1, ptr %b2, ptr %b3) { |
| ; CHECK-YES-LABEL: define i32 @test12( |
| ; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-YES: [[LOOP]]: |
| ; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[BACKEDGE:.*]] ] |
| ; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[BACKEDGE]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[BACKEDGE]] ] |
| ; CHECK-YES-NEXT: [[B4:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B5:%.*]], %[[BACKEDGE]] ] |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ] |
| ; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[B6:%.*]] = phi ptr [ [[B4]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: [[A4:%.*]] = getelementptr inbounds i64, ptr [[B4]], i64 5 |
| ; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 20 |
| ; CHECK-YES-NEXT: br i1 [[CMP]], label %[[BACKEDGE]], label %[[IF_THEN_2:.*]] |
| ; CHECK-YES: [[IF_THEN_2]]: |
| ; CHECK-YES-NEXT: br label %[[BACKEDGE]] |
| ; CHECK-YES: [[BACKEDGE]]: |
| ; CHECK-YES-NEXT: [[B5]] = phi ptr [ [[B4]], %[[FALLTHROUGH]] ], [ [[B6]], %[[IF_THEN_2]] ] |
| ; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-YES-NEXT: [[CMP2:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-YES-NEXT: br i1 [[CMP2]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-YES: [[EXIT]]: |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test12( |
| ; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[LOOP:.*]] |
| ; CHECK-NO: [[LOOP]]: |
| ; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[BACKEDGE:.*]] ] |
| ; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[BACKEDGE]] ] |
| ; CHECK-NO-NEXT: [[B4:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B5:%.*]], %[[BACKEDGE]] ] |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[B6:%.*]] = phi ptr [ [[B4]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: [[A4:%.*]] = getelementptr inbounds i64, ptr [[B4]], i64 5 |
| ; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 20 |
| ; CHECK-NO-NEXT: br i1 [[CMP]], label %[[BACKEDGE]], label %[[IF_THEN_2:.*]] |
| ; CHECK-NO: [[IF_THEN_2]]: |
| ; CHECK-NO-NEXT: br label %[[BACKEDGE]] |
| ; CHECK-NO: [[BACKEDGE]]: |
| ; CHECK-NO-NEXT: [[B5]] = phi ptr [ [[B4]], %[[FALLTHROUGH]] ], [ [[B6]], %[[IF_THEN_2]] ] |
| ; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1 |
| ; CHECK-NO-NEXT: [[CMP2:%.*]] = icmp slt i32 [[IV_INC]], [[N]] |
| ; CHECK-NO-NEXT: br i1 [[CMP2]], label %[[LOOP]], label %[[EXIT:.*]] |
| ; CHECK-NO: [[EXIT]]: |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [0, %entry], [%iv.inc, %backedge] |
| %c3 = phi ptr [%a1, %entry], [%c, %backedge] |
| %b4 = phi ptr [%b1, %entry], [%b5, %backedge] |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %a2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%c3, %loop], [%a2, %if.then] |
| %b6 = phi ptr [%b4, %loop], [%b2, %if.then] |
| %v = load volatile i32, ptr %c, align 4 |
| %a4 = getelementptr inbounds i64, ptr %b4, i64 5 |
| %cmp = icmp slt i32 %iv, 20 |
| br i1 %cmp, label %backedge, label %if.then.2 |
| |
| if.then.2: |
| br label %backedge |
| |
| backedge: |
| %b5 = phi ptr [%b4, %fallthrough], [%b6, %if.then.2] |
| %iv.inc = add i32 %iv, 1 |
| %cmp2 = icmp slt i32 %iv.inc, %N |
| br i1 %cmp2, label %loop, label %exit |
| |
| exit: |
| ret i32 %v |
| } |
| |
| %struct.S = type {i32, i32} |
| ; Case with index |
| define i32 @test13(i1 %cond, ptr %b1, ptr %b2, i64 %Index) { |
| ; CHECK-YES-LABEL: define i32 @test13( |
| ; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], i64 [[INDEX:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: [[I2:%.*]] = mul i64 [[INDEX]], 2 |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = mul i64 [[INDEX]], 8 |
| ; CHECK-YES-NEXT: [[SUNKADDR1:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 [[SUNKADDR]] |
| ; CHECK-YES-NEXT: [[SUNKADDR2:%.*]] = getelementptr inbounds i8, ptr [[SUNKADDR1]], i64 4 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR2]], align 4 |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test13( |
| ; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], i64 [[INDEX:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[B1]], i64 [[INDEX]], i32 1 |
| ; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: [[I2:%.*]] = mul i64 [[INDEX]], 2 |
| ; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[B2]], i64 [[INDEX]], i32 1 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[A:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %a1 = getelementptr inbounds %struct.S, ptr %b1, i64 %Index, i32 1 |
| br i1 %cond, label %if.then, label %fallthrough |
| |
| if.then: |
| %i2 = mul i64 %Index, 2 |
| %a2 = getelementptr inbounds %struct.S, ptr %b2, i64 %Index, i32 1 |
| br label %fallthrough |
| |
| fallthrough: |
| %a = phi ptr [%a1, %entry], [%a2, %if.then] |
| %v = load i32, ptr %a, align 4 |
| ret i32 %v |
| } |
| |
| ; Select of Select case. |
| define i64 @test14(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { |
| ; CHECK-LABEL: define i64 @test14( |
| ; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[S12:%.*]] = select i1 [[C1]], ptr [[B1]], ptr [[B2]] |
| ; CHECK-NEXT: [[S21:%.*]] = select i1 [[C2]], ptr [[S12]], ptr [[B3]] |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S21]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8 |
| ; CHECK-NEXT: ret i64 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %g2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %g3 = getelementptr inbounds i64, ptr %b3, i64 5 |
| %s1 = select i1 %c1, ptr %g1, ptr %g2 |
| %s2 = select i1 %c2, ptr %s1, ptr %g3 |
| %v = load i64 , ptr %s2, align 8 |
| ret i64 %v |
| } |
| |
| ; Select of Phi case. |
| define i64 @test15(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { |
| ; CHECK-YES-LABEL: define i64 @test15( |
| ; CHECK-YES-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[SUNK_PHI]], ptr [[B3]] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S11]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8 |
| ; CHECK-YES-NEXT: ret i64 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i64 @test15( |
| ; CHECK-NO-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr [[B3]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[P1:%.*]] = phi ptr [ [[G1]], %[[ENTRY]] ], [ [[G2]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[S1:%.*]] = select i1 [[C2]], ptr [[P1]], ptr [[G3]] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i64, ptr [[S1]], align 8 |
| ; CHECK-NO-NEXT: ret i64 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %g2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %g3 = getelementptr inbounds i64, ptr %b3, i64 5 |
| br i1 %c1, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %p1 = phi ptr [%g1, %entry], [%g2, %if.then] |
| %s1 = select i1 %c2, ptr %p1, ptr %g3 |
| %v = load i64 , ptr %s1, align 8 |
| ret i64 %v |
| } |
| |
| ; Select of Phi case. Phi exists |
| define i64 @test16(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { |
| ; CHECK-LABEL: define i64 @test16( |
| ; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK: [[IF_THEN]]: |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ] |
| ; CHECK-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[P]], ptr [[B3]] |
| ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S11]], i64 40 |
| ; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8 |
| ; CHECK-NEXT: ret i64 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %g2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %g3 = getelementptr inbounds i64, ptr %b3, i64 5 |
| br i1 %c1, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %p = phi ptr [%b1, %entry], [%b2, %if.then] |
| %p1 = phi ptr [%g1, %entry], [%g2, %if.then] |
| %s1 = select i1 %c2, ptr %p1, ptr %g3 |
| %v = load i64 , ptr %s1, align 8 |
| ret i64 %v |
| } |
| |
| ; Phi of Select case. |
| define i64 @test17(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { |
| ; CHECK-YES-LABEL: define i64 @test17( |
| ; CHECK-YES-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*]]: |
| ; CHECK-YES-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[B1]], ptr [[B2]] |
| ; CHECK-YES-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B3]], %[[IF_THEN]] ], [ [[S11]], %[[ENTRY]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8 |
| ; CHECK-YES-NEXT: ret i64 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i64 @test17( |
| ; CHECK-NO-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr [[B3]], i64 5 |
| ; CHECK-NO-NEXT: [[S1:%.*]] = select i1 [[C2]], ptr [[G1]], ptr [[G2]] |
| ; CHECK-NO-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN]]: |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[P1:%.*]] = phi ptr [ [[S1]], %[[ENTRY]] ], [ [[G3]], %[[IF_THEN]] ] |
| ; CHECK-NO-NEXT: [[V:%.*]] = load i64, ptr [[P1]], align 8 |
| ; CHECK-NO-NEXT: ret i64 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b1, i64 5 |
| %g2 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %g3 = getelementptr inbounds i64, ptr %b3, i64 5 |
| %s1 = select i1 %c2, ptr %g1, ptr %g2 |
| br i1 %c1, label %if.then, label %fallthrough |
| |
| if.then: |
| br label %fallthrough |
| |
| fallthrough: |
| %p1 = phi ptr [%s1, %entry], [%g3, %if.then] |
| %v = load i64 , ptr %p1, align 8 |
| ret i64 %v |
| } |
| |
| ; The same two addr modes by different paths |
| define i32 @test18(i1 %cond1, i1 %cond2, ptr %b1, ptr %b2) { |
| ; CHECK-YES-LABEL: define i32 @test18( |
| ; CHECK-YES-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-YES-NEXT: [[ENTRY:.*:]] |
| ; CHECK-YES-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]] |
| ; CHECK-YES: [[IF_THEN1]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH:.*]] |
| ; CHECK-YES: [[IF_THEN2]]: |
| ; CHECK-YES-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-YES: [[FALLTHROUGH]]: |
| ; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN2]] ], [ [[B1]], %[[IF_THEN1]] ] |
| ; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40 |
| ; CHECK-YES-NEXT: [[V1:%.*]] = load i32, ptr [[SUNKADDR]], align 4 |
| ; CHECK-YES-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-YES-NEXT: [[V2:%.*]] = load i32, ptr [[G1_1]], align 4 |
| ; CHECK-YES-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]] |
| ; CHECK-YES-NEXT: ret i32 [[V]] |
| ; |
| ; CHECK-NO-LABEL: define i32 @test18( |
| ; CHECK-NO-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) { |
| ; CHECK-NO-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]] |
| ; CHECK-NO: [[IF_THEN1]]: |
| ; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5 |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH:.*]] |
| ; CHECK-NO: [[IF_THEN2]]: |
| ; CHECK-NO-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK-NO: [[FALLTHROUGH]]: |
| ; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[G2]], %[[IF_THEN1]] ], [ [[G1]], %[[IF_THEN2]] ] |
| ; CHECK-NO-NEXT: [[V1:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NO-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NO-NEXT: [[V2:%.*]] = load i32, ptr [[G1_1]], align 4 |
| ; CHECK-NO-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]] |
| ; CHECK-NO-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b2, i64 5 |
| br i1 %cond1, label %if.then1, label %if.then2 |
| |
| if.then1: |
| %g2 = getelementptr inbounds i64, ptr %b1, i64 5 |
| br label %fallthrough |
| |
| if.then2: |
| br i1 %cond2, label %fallthrough, label %if.then3 |
| |
| if.then3: |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%g2, %if.then1], [%g1, %if.then2], [%g1, %if.then3] |
| %v1 = load i32, ptr %c, align 4 |
| %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %v2 = load i32, ptr %g1_1, align 4 |
| %v = add i32 %v1, %v2 |
| ret i32 %v |
| } |
| |
| ; Different types but null is the first? |
| define i32 @test19(i1 %cond1, i1 %cond2, ptr %b2, ptr %b1) { |
| ; CHECK-LABEL: define i32 @test19( |
| ; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B2:%.*]], ptr [[B1:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]] |
| ; CHECK: [[IF_THEN1]]: |
| ; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[B1]], i64 40 |
| ; CHECK-NEXT: [[BC2:%.*]] = bitcast ptr [[G2]] to ptr |
| ; CHECK-NEXT: br label %[[FALLTHROUGH:.*]] |
| ; CHECK: [[IF_THEN2]]: |
| ; CHECK-NEXT: [[BC1_1:%.*]] = bitcast ptr [[G1]] to ptr |
| ; CHECK-NEXT: br i1 [[COND2]], label %[[FALLTHROUGH]], label %[[IF_THEN3:.*]] |
| ; CHECK: [[IF_THEN3]]: |
| ; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr null, i64 5 |
| ; CHECK-NEXT: [[BC1_2:%.*]] = bitcast ptr [[G3]] to ptr |
| ; CHECK-NEXT: br label %[[FALLTHROUGH]] |
| ; CHECK: [[FALLTHROUGH]]: |
| ; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[BC2]], %[[IF_THEN1]] ], [ [[BC1_1]], %[[IF_THEN2]] ], [ [[BC1_2]], %[[IF_THEN3]] ] |
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[C]], align 4 |
| ; CHECK-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5 |
| ; CHECK-NEXT: [[BC1_1_1:%.*]] = bitcast ptr [[G1_1]] to ptr |
| ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[BC1_1_1]], align 4 |
| ; CHECK-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]] |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| entry: |
| %g1 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %bc1 = bitcast ptr %g1 to ptr |
| br i1 %cond1, label %if.then1, label %if.then2 |
| |
| if.then1: |
| %g2 = getelementptr inbounds i8, ptr %b1, i64 40 |
| %bc2 = bitcast ptr %g2 to ptr |
| br label %fallthrough |
| |
| if.then2: |
| %bc1_1 = bitcast ptr %g1 to ptr |
| br i1 %cond2, label %fallthrough, label %if.then3 |
| |
| if.then3: |
| %g3 = getelementptr inbounds i64, ptr null, i64 5 |
| %bc1_2 = bitcast ptr %g3 to ptr |
| br label %fallthrough |
| |
| fallthrough: |
| %c = phi ptr [%bc2, %if.then1], [%bc1_1, %if.then2], [%bc1_2, %if.then3] |
| %v1 = load i32, ptr %c, align 4 |
| %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5 |
| %bc1_1_1 = bitcast ptr %g1_1 to ptr |
| %v2 = load i32, ptr %bc1_1_1, align 4 |
| %v = add i32 %v1, %v2 |
| ret i32 %v |
| } |