blob: 63fd1845594c6c5ef505828ff1b43ddeebbe8a69 [file] [log] [blame]
; 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
}