[llvm] 4c9d0da - Revert "[InstCombine] Fold PHIs with equal incoming pointers"

Daniil Suchkov via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 14 02:43:25 PST 2019


Author: Daniil Suchkov
Date: 2019-11-14T17:42:01+07:00
New Revision: 4c9d0da8382f176a2fb7b97298932a53d22e8627

URL: https://github.com/llvm/llvm-project/commit/4c9d0da8382f176a2fb7b97298932a53d22e8627
DIFF: https://github.com/llvm/llvm-project/commit/4c9d0da8382f176a2fb7b97298932a53d22e8627.diff

LOG: Revert "[InstCombine] Fold PHIs with equal incoming pointers"

This reverts commit a2f6ae9abffcba260c22bb235879f0576bf3b783.
It is reverted due to clang-cmake-armv7-selfhost buildbot failure.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineInternal.h
    llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
    llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 52aeb787aaf9..524f9313d8c4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -895,11 +895,6 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner
   /// insert a new pointer typed PHI and replace the original one.
   Instruction *FoldIntegerTypedPHI(PHINode &PN);
 
-  /// If all incoming values of a pointer typed PHI are pointers with the same
-  /// base and offset, replace the PHI and all incoming values with one
-  /// definition of such pointer.
-  Instruction *FoldPHIWithEqualPointers(PHINode &PN);
-
   /// Helper function for FoldPHIArgXIntoPHI() to set debug location for the
   /// folded operation.
   void PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN);

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index d1035414560b..e0376b7582f3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -1122,68 +1122,6 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
   return replaceInstUsesWith(FirstPhi, Undef);
 }
 
-Instruction *InstCombiner::FoldPHIWithEqualPointers(PHINode &PN) {
-  auto *PhiTy = dyn_cast<PointerType>(PN.getType());
-  if (!PhiTy)
-    return nullptr;
-
-  // Make sure all incoming pointers have the same base pointers and offsets.
-  // Also, make sure no addrspacecasts involved.
-  // Note: only inbounds GEPs are supported!
-  const DataLayout &DL = PN.getModule()->getDataLayout();
-  Value *FirstValue = PN.getIncomingValue(0);
-  int64_t Offset;
-  Value *Base = GetPointerBaseWithConstantOffset(
-      FirstValue, Offset, DL, /* AllowNonInbounds */ false);
-
-  auto *BaseTy = cast<PointerType>(Base->getType());
-  if (BaseTy->getAddressSpace() != PhiTy->getAddressSpace())
-    return nullptr;
-
-  for (Use &Incoming : PN.incoming_values()) {
-    if (!isa<Instruction>(Incoming))
-      return nullptr;
-    int64_t CurrentOffset;
-    Value *CurrentBase = GetPointerBaseWithConstantOffset(
-        Incoming, CurrentOffset, DL, /* AllowNonInbounds */ false);
-    if (CurrentBase != Base || CurrentOffset != Offset)
-      return nullptr;
-  }
-
-  Instruction *InsertPt = nullptr;
-  if (auto *BaseInst = dyn_cast<Instruction>(Base)) {
-    if (isa<PHINode>(BaseInst)) {
-      BasicBlock *InsertBB = BaseInst->getParent();
-      BasicBlock::iterator InsertPtIter = InsertBB->getFirstInsertionPt();
-      // Make sure the insertion point exists. At the moment the only reason why
-      // insertion point may not exist is EHPad being a terminator. This check
-      // is a bit more future-proof than just `if (!TI->isEHPad())`.
-      if (InsertPtIter != InsertBB->end())
-        InsertPt = &*InsertPtIter;
-    } else
-      InsertPt = BaseInst->getNextNode();
-  } else
-    InsertPt = &*PN.getFunction()->getEntryBlock().getFirstInsertionPt();
-
-  if (!InsertPt)
-    return nullptr;
-
-  Builder.SetInsertPoint(InsertPt);
-  Type *I8PtrTy = Builder.getInt8PtrTy(PhiTy->getAddressSpace());
-  Value *BaseI8Ptr = Builder.CreateBitCast(Base, I8PtrTy);
-  Value *GEP = Builder.CreateConstInBoundsGEP1_64(BaseI8Ptr, Offset);
-  Value *GEPTyped = Builder.CreateBitCast(GEP, PhiTy);
-
-  for (Use &Incoming : PN.incoming_values()) {
-    auto *IncomingInst = cast<Instruction>(Incoming);
-    // If we haven't already replaced this instruction.
-    if (IncomingInst != GEPTyped)
-      replaceInstUsesWith(*IncomingInst, GEPTyped);
-  }
-
-  return replaceInstUsesWith(PN, GEPTyped);
-}
-
 // PHINode simplification
 //
 Instruction *InstCombiner::visitPHINode(PHINode &PN) {
@@ -1205,9 +1143,6 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
     if (Instruction *Result = FoldPHIArgOpIntoPHI(PN))
       return Result;
 
-  if (Instruction *Result = FoldPHIWithEqualPointers(PN))
-    return Result;
-
   // If this is a trivial cycle in the PHI node graph, remove it.  Basically, if
   // this PHI only has a single use (a PHI), and if that PHI only has one use (a
   // PHI)... break the cycle.

diff  --git a/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll b/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
index 4404126c33a4..882df7b37229 100644
--- a/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
+++ b/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
@@ -13,16 +13,20 @@ define i32 @test_gep_and_bitcast(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep_and_bitcast(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -51,122 +55,23 @@ exit:
   ret i32 %res
 }
 
-define i32 @test_gep_and_bitcast_2_same_incoming_instructions(i1 %cond, i1 %cond2, i1 %cond3) {
-; ALL-LABEL: @test_gep_and_bitcast_2_same_incoming_instructions(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
-; ALL:       bb1:
-; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    br label [[EXIT:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    br i1 [[COND3:%.*]], label [[EXIT]], label [[BB3:%.*]]
-; ALL:       bb3:
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ], [ [[RES2]], [[BB3]] ]
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
-;
-entry:
-  %obj = call i8* @get_ptr.i8()
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br i1 %cond3, label %exit, label %bb3
-
-bb3:
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ], [ %ptr2.typed, %bb3 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ], [ %res2, %bb3 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
-define i32 @test_gep_and_bitcast_3_same_incoming_instructions(i1 %cond, i1 %cond2, i1 %cond3, i1 %cond4) {
-; ALL-LABEL: @test_gep_and_bitcast_3_same_incoming_instructions(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
-; ALL:       bb1:
-; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    br label [[EXIT:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    br i1 [[COND3:%.*]], label [[EXIT]], label [[BB3:%.*]]
-; ALL:       bb3:
-; ALL-NEXT:    br i1 [[COND4:%.*]], label [[EXIT]], label [[BB4:%.*]]
-; ALL:       bb4:
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ], [ [[RES2]], [[BB3]] ], [ [[RES2]], [[BB4]] ]
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
-;
-entry:
-  %obj = call i8* @get_ptr.i8()
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br i1 %cond3, label %exit, label %bb3
-
-bb3:
-  br i1 %cond4, label %exit, label %bb4
-
-bb4:
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ], [ %ptr2.typed, %bb3 ], [ %ptr2.typed, %bb4 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ], [ %res2, %bb3 ], [ %res2, %bb4 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
 define i32 @test_gep_and_bitcast_arg(i8* %obj, i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep_and_bitcast_arg(
 ; ALL-NEXT:  entry:
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ:%.*]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ:%.*]], i64 16
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -208,17 +113,21 @@ define i32 @test_gep_and_bitcast_phi(i1 %cond, i1 %cond2, i1 %cond3) {
 ; ALL:       merge:
 ; ALL-NEXT:    [[OBJ:%.*]] = phi i8* [ [[OBJ1]], [[BB1]] ], [ [[OBJ2]], [[BB2]] ]
 ; ALL-NEXT:    [[ANOTHER_PHI:%.*]] = phi i8* [ [[OBJ1]], [[BB1]] ], [ null, [[BB2]] ]
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    call void @foo.i8(i8* [[ANOTHER_PHI]])
 ; ALL-NEXT:    br i1 [[COND2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
 ; ALL:       bb3:
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb4:
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB3]] ], [ [[PTR2_TYPED]], [[BB4]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB3]] ], [ [[PTR2_TYPED]], [[BB4]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND3:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -265,15 +174,18 @@ define i32 @test_gep_i32ptr(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep_i32ptr(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i32* @get_ptr.i32()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[OBJ]], i64 16
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = getelementptr inbounds i32, i32* [[OBJ]], i64 16
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = getelementptr inbounds i32, i32* [[OBJ]], i64 16
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP0]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP0]], align 4
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -304,16 +216,20 @@ define i32 @test_gep_and_bitcast_gep_base_ptr(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep_and_bitcast_gep_base_ptr(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ0:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ0]], i64 32
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ0]], i64 32
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ0]], i64 32
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -344,19 +260,37 @@ exit:
 }
 
 define i32 @test_gep_and_bitcast_same_bb(i1 %cond, i1 %cond2) {
-; ALL-LABEL: @test_gep_and_bitcast_same_bb(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
+; INSTCOMBINE-LABEL: @test_gep_and_bitcast_same_bb(
+; INSTCOMBINE-NEXT:  entry:
+; INSTCOMBINE-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
+; INSTCOMBINE-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINE-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; INSTCOMBINE-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
+; INSTCOMBINE:       bb2:
+; INSTCOMBINE-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINE-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
+; INSTCOMBINE-NEXT:    br label [[EXIT]]
+; INSTCOMBINE:       exit:
+; INSTCOMBINE-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[ENTRY:%.*]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; INSTCOMBINE-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[ENTRY]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; INSTCOMBINE-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
+; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
+; INSTCOMBINE-NEXT:    ret i32 [[RES]]
+;
+; INSTCOMBINEGVN-LABEL: @test_gep_and_bitcast_same_bb(
+; INSTCOMBINEGVN-NEXT:  entry:
+; INSTCOMBINEGVN-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
+; INSTCOMBINEGVN-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINEGVN-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; INSTCOMBINEGVN-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
+; INSTCOMBINEGVN:       bb2:
+; INSTCOMBINEGVN-NEXT:    br label [[EXIT]]
+; INSTCOMBINEGVN:       exit:
+; INSTCOMBINEGVN-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
+; INSTCOMBINEGVN-NEXT:    store i32 1, i32* [[PTR1_TYPED]], align 4
+; INSTCOMBINEGVN-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
+; INSTCOMBINEGVN-NEXT:    ret i32 [[RES]]
 ;
 entry:
   %obj = call i8* @get_ptr.i8()
@@ -381,20 +315,39 @@ exit:
 }
 
 define i32 @test_gep_and_bitcast_same_bb_and_extra_use(i1 %cond, i1 %cond2) {
-; ALL-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[TMP1]])
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
+; INSTCOMBINE-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(
+; INSTCOMBINE-NEXT:  entry:
+; INSTCOMBINE-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
+; INSTCOMBINE-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINE-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; INSTCOMBINE-NEXT:    call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
+; INSTCOMBINE-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
+; INSTCOMBINE:       bb2:
+; INSTCOMBINE-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINE-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
+; INSTCOMBINE-NEXT:    br label [[EXIT]]
+; INSTCOMBINE:       exit:
+; INSTCOMBINE-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[ENTRY:%.*]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; INSTCOMBINE-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[ENTRY]] ], [ [[PTR2_TYPED]], [[BB2]] ]
+; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
+; INSTCOMBINE-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
+; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
+; INSTCOMBINE-NEXT:    ret i32 [[RES]]
+;
+; INSTCOMBINEGVN-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(
+; INSTCOMBINEGVN-NEXT:  entry:
+; INSTCOMBINEGVN-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
+; INSTCOMBINEGVN-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; INSTCOMBINEGVN-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; INSTCOMBINEGVN-NEXT:    call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
+; INSTCOMBINEGVN-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
+; INSTCOMBINEGVN:       bb2:
+; INSTCOMBINEGVN-NEXT:    br label [[EXIT]]
+; INSTCOMBINEGVN:       exit:
+; INSTCOMBINEGVN-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
+; INSTCOMBINEGVN-NEXT:    store i32 1, i32* [[PTR1_TYPED]], align 4
+; INSTCOMBINEGVN-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
+; INSTCOMBINEGVN-NEXT:    ret i32 [[RES]]
 ;
 entry:
   %obj = call i8* @get_ptr.i8()
@@ -423,15 +376,18 @@ define i8 @test_gep(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i8, i8* [[TMP0]], align 1
-; ALL-NEXT:    store i8 1, i8* [[TMP0]], align 1
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i8* [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i8* [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]
+; ALL-NEXT:    [[RES_PHI:%.*]] = load i8, i8* [[RES_PHI_IN]], align 1
+; ALL-NEXT:    store i8 1, i8* [[PTR_TYPED]], align 1
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1
 ; ALL-NEXT:    ret i8 [[RES]]
 ;
@@ -462,20 +418,23 @@ define i32 @test_extra_uses(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_extra_uses(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
-; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[TMP1]])
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
+; ALL-NEXT:    call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
-; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[TMP1]])
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
+; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
+; ALL-NEXT:    call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
 ; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -561,20 +520,23 @@ define i32 @test_extra_uses_multiple_geps(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_extra_uses_multiple_geps(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32*
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
-; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[TMP1]])
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
+; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
+; ALL-NEXT:    call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
-; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[TMP1]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[TMP1]])
+; ALL-NEXT:    [[PTR2_1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2_1]] to i32*
+; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
+; ALL-NEXT:    call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
 ; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
-; ALL-NEXT:    store i32 1, i32* [[TMP1]], align 4
+; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
 ; ALL-NEXT:    ret i32 [[RES]]
 ;
@@ -610,19 +572,21 @@ define i8 @test_gep_extra_uses(i1 %cond, i1 %cond2) {
 ; ALL-LABEL: @test_gep_extra_uses(
 ; ALL-NEXT:  entry:
 ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
 ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; ALL:       bb1:
-; ALL-NEXT:    [[RES1:%.*]] = load i8, i8* [[TMP0]], align 1
-; ALL-NEXT:    call void @foo.i8(i8* nonnull [[TMP0]])
+; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[RES1:%.*]] = load i8, i8* [[PTR1]], align 1
+; ALL-NEXT:    call void @foo.i8(i8* nonnull [[PTR1]])
 ; ALL-NEXT:    br label [[EXIT:%.*]]
 ; ALL:       bb2:
-; ALL-NEXT:    [[RES2:%.*]] = load i8, i8* [[TMP0]], align 1
-; ALL-NEXT:    call void @foo.i8(i8* nonnull [[TMP0]])
+; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
+; ALL-NEXT:    [[RES2:%.*]] = load i8, i8* [[PTR2]], align 1
+; ALL-NEXT:    call void @foo.i8(i8* nonnull [[PTR2]])
 ; ALL-NEXT:    br label [[EXIT]]
 ; ALL:       exit:
+; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i8* [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]
 ; ALL-NEXT:    [[RES_PHI:%.*]] = phi i8 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
-; ALL-NEXT:    store i8 1, i8* [[TMP0]], align 1
+; ALL-NEXT:    store i8 1, i8* [[PTR_TYPED]], align 1
 ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1
 ; ALL-NEXT:    ret i8 [[RES]]
 ;
@@ -650,231 +614,3 @@ exit:
   %res = select i1 %cond2, i8 %res.phi, i8 %res.load
   ret i8 %res
 }
-
-define i32 @test_neg_extra_uses_inbounds_mismatch(i1 %cond, i1 %cond2) {
-; ALL-LABEL: @test_neg_extra_uses_inbounds_mismatch(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
-; ALL:       bb1:
-; ALL-NEXT:    [[PTR1:%.*]] = getelementptr i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
-; ALL-NEXT:    [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* [[PTR1_TYPED]])
-; ALL-NEXT:    br label [[EXIT:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
-; ALL-NEXT:    [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
-; ALL-NEXT:    call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
-; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
-; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
-;
-entry:
-  %obj = call i8* @get_ptr.i8()
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  call void @foo.i32(i32* %ptr1.typed)
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  call void @foo.i32(i32* %ptr2.typed)
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
-define i32 @test_neg_gep_and_bitcast_
diff erent_offset(i1 %cond, i1 %cond2) {
-; ALL-LABEL: @test_neg_gep_and_bitcast_
diff erent_offset(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
-; ALL:       bb1:
-; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
-; ALL-NEXT:    br label [[EXIT:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 20
-; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
-; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
-; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
-;
-entry:
-  %obj = call i8* @get_ptr.i8()
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 20
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
-define i32 @test_neg_gep_and_bitcast_
diff erent_base_ptr(i1 %cond, i1 %cond2) {
-; ALL-LABEL: @test_neg_gep_and_bitcast_
diff erent_base_ptr(
-; ALL-NEXT:  entry:
-; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    [[OBJ2:%.*]] = call i8* @get_ptr.i8()
-; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
-; ALL:       bb1:
-; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
-; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
-; ALL-NEXT:    br label [[EXIT:%.*]]
-; ALL:       bb2:
-; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ2]], i64 16
-; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
-; ALL-NEXT:    br label [[EXIT]]
-; ALL:       exit:
-; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
-; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
-; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]], align 4
-; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
-; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
-; ALL-NEXT:    ret i32 [[RES]]
-;
-entry:
-  %obj = call i8* @get_ptr.i8()
-  %obj2 = call i8* @get_ptr.i8()
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj2, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
-; Just to make sure we don't generate invalid IR in this case.
-; There is no insertion point right after base pointer def here.
-define i32 @test_neg_gep_and_bitcast_invoke(i1 %cond, i1 %cond2) personality i8 0 {
-; ALL-LABEL: @test_neg_gep_and_bitcast_invoke(
-;
-entry:
-  %obj = invoke i8* @get_ptr.i8() to label %bb0 unwind label %lpad
-
-lpad:
-  %ll = landingpad { i8*, i32 }
-  cleanup
-  ret i32 0
-
-bb0:
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-}
-
-; Just to make sure we don't generate invalid IR in this case.
-define i32 @test_neg_gep_and_bitcast_phi_no_insert_pt(i1 %cond, i1 %cond2) personality i8 0 {
-; ALL-LABEL: @test_neg_gep_and_bitcast_phi_no_insert_pt(
-;
-entry:
-  %obj1 = call i8* @get_ptr.i8()
-  invoke void @foo.i8(i8* null) to label %cont unwind label %catch
-
-cont:
-  %obj2.typed = call i32* @get_ptr.i32()
-  %obj2 = bitcast i32* %obj2.typed to i8*
-  invoke void @foo.i8(i8* null) to label %unreachable unwind label %catch
-
-catch:
-  ; There is no insertion point in this basic block!
-  %obj = phi i8* [ %obj1, %entry ], [ %obj2, %cont ]
-  %cs = catchswitch within none [label %doit] unwind to caller
-
-doit:
-  %cl = catchpad within %cs []
-  br i1 %cond, label %bb1, label %bb2
-
-bb1:
-  %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr1.typed = bitcast i8* %ptr1 to i32*
-  %res1 = load i32, i32* %ptr1.typed
-  br label %exit
-
-bb2:
-  %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
-  %ptr2.typed = bitcast i8* %ptr2 to i32*
-  %res2 = load i32, i32* %ptr2.typed
-  br label %exit
-
-exit:
-  %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
-  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
-  store i32 1, i32* %ptr.typed
-  %res.load = load i32, i32* %ptr.typed
-  %res = select i1 %cond2, i32 %res.phi, i32 %res.load
-  ret i32 %res
-
-unreachable:
-  unreachable
-}


        


More information about the llvm-commits mailing list