; 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
}

; Make sure we don't simplify an incomplete expression tree.
define i8 @pr163453(ptr %p, i1 %cond) {
; CHECK-LABEL: define i8 @pr163453(
; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[P_ADDR_0:%.*]] = getelementptr i8, ptr [[P]], i64 1
; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT:    [[INCDEC_PTR11:%.*]] = getelementptr i8, ptr [[P]], i64 2
; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND]], ptr [[P_ADDR_0]], ptr [[INCDEC_PTR11]]
; CHECK-NEXT:    [[LOAD:%.*]] = load i8, ptr [[SPEC_SELECT]], align 1
; CHECK-NEXT:    ret i8 [[LOAD]]
;
entry:
  br label %for.cond

for.cond:
  %p.pn = phi ptr [ %p, %entry ], [ %p.addr.0, %for.inc ]
  %p.addr.0 = getelementptr i8, ptr %p.pn, i64 1
  br i1 false, label %exit, label %for.body

for.body:
  %1 = load i8, ptr %p.pn, align 1
  br i1 false, label %for.inc, label %if.else

if.else:
  %incdec.ptr11 = getelementptr i8, ptr %p.pn, i64 2
  %spec.select = select i1 %cond, ptr %p.addr.0, ptr %incdec.ptr11
  br label %exit

for.inc:
  br label %for.cond

exit:
  %p.addr.3 = phi ptr [ %spec.select, %if.else ], [ %p.addr.0, %for.cond ]
  %load = load i8, ptr %p.addr.3, align 1
  ret i8 %load
}
