From 5165ff9878bba031b95756e2de12d4025da69a92 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Wed, 22 Oct 2014 12:18:48 +0000 Subject: [PATCH] [InstSimplify] Support constant folding to vector of pointers ConstantFolding crashes when trying to InstSimplify the following load: @a = private unnamed_addr constant %mst { i8* inttoptr (i64 -1 to i8*), i8* inttoptr (i64 -1 to i8*) }, align 8 %x = load <2 x i8*>* bitcast (%mst* @a to <2 x i8*>*), align 8 This patch fix this by adding support to this type of folding: %x = load <2 x i8*>* bitcast (%mst* @a to <2 x i8*>*), align 8 ==> gets folded to: %x = <2 x i8*> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220380 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ConstantFolding.cpp | 14 ++++++-- .../InstSimplify/vector_ptr_bitcast.ll | 35 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/InstSimplify/vector_ptr_bitcast.ll diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 3441ec383a3..cd25acb9ba9 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -55,7 +55,8 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, // 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 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, // 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 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, 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)); } diff --git a/test/Transforms/InstSimplify/vector_ptr_bitcast.ll b/test/Transforms/InstSimplify/vector_ptr_bitcast.ll new file mode 100644 index 00000000000..607892ae74d --- /dev/null +++ b/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 +}