forked from OSchip/llvm-project
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. llvm-svn: 191143
This commit is contained in:
parent
ff29d538ea
commit
90901a35ce
|
@ -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.
|
||||
|
|
|
@ -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