mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
[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*)> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220380 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8546076401
commit
5165ff9878
@ -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));
|
||||
}
|
||||
|
35
test/Transforms/InstSimplify/vector_ptr_bitcast.ll
Normal file
35
test/Transforms/InstSimplify/vector_ptr_bitcast.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user