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. @@ -195,9 +196,12 @@ return ConstantVector::get(Result); } - // Handle: bitcast (<2 x i64> to <4 x i32>) + // Handle: bitcast (<2 x i64> to <4 x i32>) and + // bitcast (<1 x i128> to <2 x i8*>) + bool IsDstEltTyPtr = DstEltTy->isPointerTy(); unsigned Ratio = NumDstElt/NumSrcElt; - unsigned DstBitSize = DstEltTy->getPrimitiveSizeInBits(); + unsigned DstBitSize = IsDstEltTyPtr ? TD.getPointerTypeSizeInBits(DstEltTy) + : DstEltTy->getPrimitiveSizeInBits(); // Loop over each source value, expanding into multiple results. for (unsigned i = 0; i != NumSrcElt; ++i) { @@ -213,6 +217,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 (IsDstEltTyPtr) { + 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,17 @@ +; RUN: opt -S -instsimplify < %s | FileCheck %s +target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" + +%mst = type { i8*, i8* } + +@a = private unnamed_addr constant %mst { i8* inttoptr (i64 -1 to i8*), + i8* inttoptr (i64 -1 to i8*)}, + align 8 + +define void @fn() { + %x = load <2 x i8*>* bitcast (%mst* @a to <2 x i8*>*), align 8 + %b = extractelement <2 x i8*> %x, i32 0 + ; CHECK-LABEL: @fn + ; CHECK-NEXT: ret void + ret void +} +