mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
SROA: Handle casts involving vectors of pointers and integer scalars.
SROA wants to convert any types of equivalent widths but it's not possible to convert vectors of pointers to an integer scalar with a single cast. As a workaround we add a bitcast to the corresponding int ptr type first. This type of cast used to be an edge case but has become common with SLP vectorization. Fixes PR17271. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191143 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
189c6235e7
commit
1ce1525ed4
@ -1452,6 +1452,10 @@ static bool canConvertValue(const DataLayout &DL, Type *OldTy, Type *NewTy) {
|
||||
if (!NewTy->isSingleValueType() || !OldTy->isSingleValueType())
|
||||
return false;
|
||||
|
||||
// We handle can convert pointers to integers and vice-versa. Same for vectors
|
||||
// of pointers and integers.
|
||||
OldTy = OldTy->getScalarType();
|
||||
NewTy = NewTy->getScalarType();
|
||||
if (NewTy->isPointerTy() || OldTy->isPointerTy()) {
|
||||
if (NewTy->isPointerTy() && OldTy->isPointerTy())
|
||||
return true;
|
||||
@ -1470,21 +1474,53 @@ static bool canConvertValue(const DataLayout &DL, Type *OldTy, Type *NewTy) {
|
||||
/// inttoptr, and ptrtoint casts. Use the \c canConvertValue predicate to test
|
||||
/// two types for viability with this routine.
|
||||
static Value *convertValue(const DataLayout &DL, IRBuilderTy &IRB, Value *V,
|
||||
Type *Ty) {
|
||||
assert(canConvertValue(DL, V->getType(), Ty) &&
|
||||
"Value not convertable to type");
|
||||
if (V->getType() == Ty)
|
||||
Type *NewTy) {
|
||||
Type *OldTy = V->getType();
|
||||
assert(canConvertValue(DL, OldTy, NewTy) && "Value not convertable to type");
|
||||
|
||||
if (OldTy == NewTy)
|
||||
return V;
|
||||
if (IntegerType *OldITy = dyn_cast<IntegerType>(V->getType()))
|
||||
if (IntegerType *NewITy = dyn_cast<IntegerType>(Ty))
|
||||
|
||||
if (IntegerType *OldITy = dyn_cast<IntegerType>(OldTy))
|
||||
if (IntegerType *NewITy = dyn_cast<IntegerType>(NewTy))
|
||||
if (NewITy->getBitWidth() > OldITy->getBitWidth())
|
||||
return IRB.CreateZExt(V, NewITy);
|
||||
if (V->getType()->isIntegerTy() && Ty->isPointerTy())
|
||||
return IRB.CreateIntToPtr(V, Ty);
|
||||
if (V->getType()->isPointerTy() && Ty->isIntegerTy())
|
||||
return IRB.CreatePtrToInt(V, Ty);
|
||||
|
||||
return IRB.CreateBitCast(V, Ty);
|
||||
// See if we need inttoptr for this type pair. A cast involving both scalars
|
||||
// and vectors requires and additional bitcast.
|
||||
if (OldTy->getScalarType()->isIntegerTy() &&
|
||||
NewTy->getScalarType()->isPointerTy()) {
|
||||
// Expand <2 x i32> to i8* --> <2 x i32> to i64 to i8*
|
||||
if (OldTy->isVectorTy() && !NewTy->isVectorTy())
|
||||
return IRB.CreateIntToPtr(IRB.CreateBitCast(V, DL.getIntPtrType(NewTy)),
|
||||
NewTy);
|
||||
|
||||
// Expand i128 to <2 x i8*> --> i128 to <2 x i64> to <2 x i8*>
|
||||
if (!OldTy->isVectorTy() && NewTy->isVectorTy())
|
||||
return IRB.CreateIntToPtr(IRB.CreateBitCast(V, DL.getIntPtrType(NewTy)),
|
||||
NewTy);
|
||||
|
||||
return IRB.CreateIntToPtr(V, NewTy);
|
||||
}
|
||||
|
||||
// See if we need ptrtoint for this type pair. A cast involving both scalars
|
||||
// and vectors requires and additional bitcast.
|
||||
if (OldTy->getScalarType()->isPointerTy() &&
|
||||
NewTy->getScalarType()->isIntegerTy()) {
|
||||
// Expand <2 x i8*> to i128 --> <2 x i8*> to <2 x i64> to i128
|
||||
if (OldTy->isVectorTy() && !NewTy->isVectorTy())
|
||||
return IRB.CreateBitCast(IRB.CreatePtrToInt(V, DL.getIntPtrType(OldTy)),
|
||||
NewTy);
|
||||
|
||||
// Expand i8* to <2 x i32> --> i8* to i64 to <2 x i32>
|
||||
if (!OldTy->isVectorTy() && NewTy->isVectorTy())
|
||||
return IRB.CreateBitCast(IRB.CreatePtrToInt(V, DL.getIntPtrType(OldTy)),
|
||||
NewTy);
|
||||
|
||||
return IRB.CreatePtrToInt(V, NewTy);
|
||||
}
|
||||
|
||||
return IRB.CreateBitCast(V, NewTy);
|
||||
}
|
||||
|
||||
/// \brief Test whether the given slice use can be promoted to a vector.
|
||||
|
53
test/Transforms/SROA/vector-conversion.ll
Normal file
53
test/Transforms/SROA/vector-conversion.ll
Normal file
@ -0,0 +1,53 @@
|
||||
; RUN: opt < %s -sroa -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
|
||||
|
||||
define <4 x i64> @vector_ptrtoint({<2 x i32*>, <2 x i32*>} %x) {
|
||||
; CHECK-LABEL: @vector_ptrtoint
|
||||
%a = alloca {<2 x i32*>, <2 x i32*>}
|
||||
; CHECK-NOT: alloca
|
||||
|
||||
store {<2 x i32*>, <2 x i32*>} %x, {<2 x i32*>, <2 x i32*>}* %a
|
||||
; CHECK-NOT: store
|
||||
|
||||
%cast = bitcast {<2 x i32*>, <2 x i32*>}* %a to <4 x i64>*
|
||||
%vec = load <4 x i64>* %cast
|
||||
; CHECK-NOT: load
|
||||
; CHECK: ptrtoint
|
||||
|
||||
ret <4 x i64> %vec
|
||||
}
|
||||
|
||||
define <4 x i32*> @vector_inttoptr({<2 x i64>, <2 x i64>} %x) {
|
||||
; CHECK-LABEL: @vector_inttoptr
|
||||
%a = alloca {<2 x i64>, <2 x i64>}
|
||||
; CHECK-NOT: alloca
|
||||
|
||||
store {<2 x i64>, <2 x i64>} %x, {<2 x i64>, <2 x i64>}* %a
|
||||
; CHECK-NOT: store
|
||||
|
||||
%cast = bitcast {<2 x i64>, <2 x i64>}* %a to <4 x i32*>*
|
||||
%vec = load <4 x i32*>* %cast
|
||||
; CHECK-NOT: load
|
||||
; CHECK: inttoptr
|
||||
|
||||
ret <4 x i32*> %vec
|
||||
}
|
||||
|
||||
define <2 x i64> @vector_ptrtointbitcast({<1 x i32*>, <1 x i32*>} %x) {
|
||||
; CHECK-LABEL: @vector_ptrtointbitcast
|
||||
%a = alloca {<1 x i32*>, <1 x i32*>}
|
||||
; CHECK-NOT: alloca
|
||||
|
||||
store {<1 x i32*>, <1 x i32*>} %x, {<1 x i32*>, <1 x i32*>}* %a
|
||||
; CHECK-NOT: store
|
||||
|
||||
%cast = bitcast {<1 x i32*>, <1 x i32*>}* %a to <2 x i64>*
|
||||
%vec = load <2 x i64>* %cast
|
||||
; CHECK-NOT: load
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: bitcast
|
||||
; CHECK: ptrtoint
|
||||
; CHECK: bitcast
|
||||
|
||||
ret <2 x i64> %vec
|
||||
}
|
Loading…
Reference in New Issue
Block a user