[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*> <i8* inttoptr (i64 -1 to i8*), i8* inttoptr (i64 -1 to i8*)>

llvm-svn: 220380
This commit is contained in:
Bruno Cardoso Lopes 2014-10-22 12:18:48 +00:00
parent 3b68607eac
commit c29520c5b3
2 changed files with 47 additions and 2 deletions

View File

@ -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> <i64 0, i64 1> 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));
}

View File

@ -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
}