Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -55,7 +55,8 @@ // Catch the obvious splat cases. if (C->isNullValue() && !DestTy->isX86_MMXTy()) return Constant::getNullValue(DestTy); - if (C->isAllOnesValue() && !DestTy->isX86_MMXTy()) + if (C->isAllOnesValue() && !DestTy->isX86_MMXTy() && + !DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types! return Constant::getAllOnesValue(DestTy); // Handle a vector->integer cast. @@ -197,7 +198,7 @@ // Handle: bitcast (<2 x i64> to <4 x i32>) unsigned Ratio = NumDstElt/NumSrcElt; - unsigned DstBitSize = DstEltTy->getPrimitiveSizeInBits(); + unsigned DstBitSize = TD.getTypeSizeInBits(DstEltTy); // Loop over each source value, expanding into multiple results. for (unsigned i = 0; i != NumSrcElt; ++i) { @@ -213,6 +214,15 @@ ConstantInt::get(Src->getType(), ShiftAmt)); ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize; + // Truncate the element to an integer with the same pointer size and + // convert the element back to a pointer using a inttoptr. + if (DstEltTy->isPointerTy()) { + IntegerType *DstIntTy = Type::getIntNTy(C->getContext(), DstBitSize); + Constant *CE = ConstantExpr::getTrunc(Elt, DstIntTy); + Result.push_back(ConstantExpr::getIntToPtr(CE, DstEltTy)); + continue; + } + // Truncate and remember this piece. Result.push_back(ConstantExpr::getTrunc(Elt, DstEltTy)); } Index: test/Transforms/InstSimplify/vector_ptr_bitcast.ll =================================================================== --- /dev/null +++ test/Transforms/InstSimplify/vector_ptr_bitcast.ll @@ -0,0 +1,35 @@ +; RUN: opt -S -instsimplify < %s | FileCheck %s +target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" + +%mst = type { i8*, i8* } +%mst2 = type { i32*, i32*, i32*, i32* } + +@a = private unnamed_addr constant %mst { i8* inttoptr (i64 -1 to i8*), + i8* inttoptr (i64 -1 to i8*)}, + align 8 +@b = private unnamed_addr constant %mst2 { i32* inttoptr (i64 42 to i32*), + i32* inttoptr (i64 67 to i32*), + i32* inttoptr (i64 33 to i32*), + i32* inttoptr (i64 58 to i32*)}, + align 8 + +define i64 @fn() { + %x = load <2 x i8*>* bitcast (%mst* @a to <2 x i8*>*), align 8 + %b = extractelement <2 x i8*> %x, i32 0 + %c = ptrtoint i8* %b to i64 + ; CHECK-LABEL: @fn + ; CHECK-NEXT: ret i64 -1 + ret i64 %c +} + +define i64 @fn2() { + %x = load <4 x i32*>* bitcast (%mst2* @b to <4 x i32*>*), align 8 + %b = extractelement <4 x i32*> %x, i32 0 + %c = extractelement <4 x i32*> %x, i32 3 + %d = ptrtoint i32* %b to i64 + %e = ptrtoint i32* %c to i64 + %r = add i64 %d, %e + ; CHECK-LABEL: @fn2 + ; CHECK-NEXT: ret i64 100 + ret i64 %r +}