Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3488,7 +3488,7 @@ Value *llvm::GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup) { - if (!V->getType()->isPointerTy()) + if (!V->getType()->isPtrOrPtrVectorTy()) return V; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { if (GEPOperator *GEP = dyn_cast(V)) { @@ -3530,7 +3530,7 @@ return V; } - assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + assert(V->getType()->isPtrOrPtrVectorTy() && "Unexpected operand type!"); } return V; } Index: unittests/Analysis/ValueTrackingTest.cpp =================================================================== --- unittests/Analysis/ValueTrackingTest.cpp +++ unittests/Analysis/ValueTrackingTest.cpp @@ -313,3 +313,51 @@ EXPECT_EQ(Known.One.getZExtValue(), 32u); EXPECT_EQ(Known.Zero.getZExtValue(), 95u); } + +TEST(ValueTracking, GetUnderlyingObjectForBitcastVector) { + StringRef Assembly = "define <1 x i32*> @f() { " + " %a = alloca i64 " + " %b = bitcast i64* %a to <1 x i32*>" + " ret <1 x i32*> %b " + "} "; + + LLVMContext Context; + SMDiagnostic Error; + auto M = parseAssemblyString(Assembly, Error, Context); + assert(M && "Bad assembly?"); + + const DataLayout &DL = M->getDataLayout(); + + auto *F = M->getFunction("f"); + assert(F && "Bad assembly?"); + + auto &BB = F->getEntryBlock(); + + auto *RVal = cast(BB.getTerminator())->getOperand(0); + auto *Alloc = GetUnderlyingObject(RVal, DL); + EXPECT_EQ(Alloc, &*BB.begin()); +} + +TEST(ValueTracking, GetUnderlyingObjectForGepVector) { + StringRef Assembly = "define <2 x i64*> @f() { " + " %a = alloca i64 " + " %g = getelementptr inbounds i64, i64* %a, <2 x i64> " + " ret <2 x i64*> %g" + "} "; + + LLVMContext Context; + SMDiagnostic Error; + auto M = parseAssemblyString(Assembly, Error, Context); + assert(M && "Bad assembly?"); + + const DataLayout &DL = M->getDataLayout(); + + auto *F = M->getFunction("f"); + assert(F && "Bad assembly?"); + + auto &BB = F->getEntryBlock(); + + auto *RVal = cast(BB.getTerminator())->getOperand(0); + auto *Alloc = GetUnderlyingObject(RVal, DL); + EXPECT_EQ(Alloc, &*BB.begin()); +}