mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[SVE] Eliminate bad VectorType::getNumElements() calls from ConstantFold
Summary: Assume all usages of this function are explicitly fixed-width operations and cast to FixedVectorType Reviewers: efriedma, sdesmalen, c-rhodes, majnemer, dblaikie Reviewed By: sdesmalen Subscribers: tschuett, hiraditya, rkruppe, psnobl, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D80262
This commit is contained in:
parent
a01428816d
commit
faa78a0019
@ -55,8 +55,8 @@ static Constant *BitCastConstantVector(Constant *CV, VectorType *DstTy) {
|
|||||||
// If this cast changes element count then we can't handle it here:
|
// If this cast changes element count then we can't handle it here:
|
||||||
// doing so requires endianness information. This should be handled by
|
// doing so requires endianness information. This should be handled by
|
||||||
// Analysis/ConstantFolding.cpp
|
// Analysis/ConstantFolding.cpp
|
||||||
unsigned NumElts = DstTy->getNumElements();
|
unsigned NumElts = cast<FixedVectorType>(DstTy)->getNumElements();
|
||||||
if (NumElts != cast<VectorType>(CV->getType())->getNumElements())
|
if (NumElts != cast<FixedVectorType>(CV->getType())->getNumElements())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Type *DstEltTy = DstTy->getElementType();
|
Type *DstEltTy = DstTy->getElementType();
|
||||||
@ -573,8 +573,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
|
|||||||
// count may be mismatched; don't attempt to handle that here.
|
// count may be mismatched; don't attempt to handle that here.
|
||||||
if ((isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) &&
|
if ((isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) &&
|
||||||
DestTy->isVectorTy() &&
|
DestTy->isVectorTy() &&
|
||||||
cast<VectorType>(DestTy)->getNumElements() ==
|
cast<FixedVectorType>(DestTy)->getNumElements() ==
|
||||||
cast<VectorType>(V->getType())->getNumElements()) {
|
cast<FixedVectorType>(V->getType())->getNumElements()) {
|
||||||
VectorType *DestVecTy = cast<VectorType>(DestTy);
|
VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||||
Type *DstEltTy = DestVecTy->getElementType();
|
Type *DstEltTy = DestVecTy->getElementType();
|
||||||
// Fast path for splatted constants.
|
// Fast path for splatted constants.
|
||||||
@ -585,7 +585,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
|
|||||||
}
|
}
|
||||||
SmallVector<Constant *, 16> res;
|
SmallVector<Constant *, 16> res;
|
||||||
Type *Ty = IntegerType::get(V->getContext(), 32);
|
Type *Ty = IntegerType::get(V->getContext(), 32);
|
||||||
for (unsigned i = 0, e = cast<VectorType>(V->getType())->getNumElements();
|
for (unsigned i = 0,
|
||||||
|
e = cast<FixedVectorType>(V->getType())->getNumElements();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
Constant *C =
|
Constant *C =
|
||||||
ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
|
ConstantExpr::getExtractElement(V, ConstantInt::get(Ty, i));
|
||||||
@ -809,9 +810,11 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
|
|||||||
if (!CIdx)
|
if (!CIdx)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (auto *ValFVTy = dyn_cast<FixedVectorType>(Val->getType())) {
|
||||||
// ee({w,x,y,z}, wrong_value) -> undef
|
// ee({w,x,y,z}, wrong_value) -> undef
|
||||||
if (CIdx->uge(ValVTy->getNumElements()))
|
if (CIdx->uge(ValFVTy->getNumElements()))
|
||||||
return UndefValue::get(ValVTy->getElementType());
|
return UndefValue::get(ValFVTy->getElementType());
|
||||||
|
}
|
||||||
|
|
||||||
// ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...)
|
// ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...)
|
||||||
if (auto *CE = dyn_cast<ConstantExpr>(Val)) {
|
if (auto *CE = dyn_cast<ConstantExpr>(Val)) {
|
||||||
@ -833,6 +836,16 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CAZ of type ScalableVectorType and n < CAZ->getMinNumElements() =>
|
||||||
|
// extractelt CAZ, n -> 0
|
||||||
|
if (auto *ValSVTy = dyn_cast<ScalableVectorType>(Val->getType())) {
|
||||||
|
if (!CIdx->uge(ValSVTy->getMinNumElements())) {
|
||||||
|
if (auto *CAZ = dyn_cast<ConstantAggregateZero>(Val))
|
||||||
|
return CAZ->getElementValue(CIdx->getZExtValue());
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return Val->getAggregateElement(CIdx);
|
return Val->getAggregateElement(CIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,11 +860,12 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
|
|||||||
|
|
||||||
// Do not iterate on scalable vector. The num of elements is unknown at
|
// Do not iterate on scalable vector. The num of elements is unknown at
|
||||||
// compile-time.
|
// compile-time.
|
||||||
VectorType *ValTy = cast<VectorType>(Val->getType());
|
if (isa<ScalableVectorType>(Val->getType()))
|
||||||
if (isa<ScalableVectorType>(ValTy))
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
unsigned NumElts = cast<VectorType>(Val->getType())->getNumElements();
|
auto *ValTy = cast<FixedVectorType>(Val->getType());
|
||||||
|
|
||||||
|
unsigned NumElts = ValTy->getNumElements();
|
||||||
if (CIdx->uge(NumElts))
|
if (CIdx->uge(NumElts))
|
||||||
return UndefValue::get(Val->getType());
|
return UndefValue::get(Val->getType());
|
||||||
|
|
||||||
@ -898,7 +912,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
|
|||||||
if (isa<ScalableVectorType>(V1VTy))
|
if (isa<ScalableVectorType>(V1VTy))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
unsigned SrcNumElts = V1VTy->getNumElements();
|
unsigned SrcNumElts = V1VTy->getElementCount().Min;
|
||||||
|
|
||||||
// Loop over the shuffle mask, evaluating each element.
|
// Loop over the shuffle mask, evaluating each element.
|
||||||
SmallVector<Constant*, 32> Result;
|
SmallVector<Constant*, 32> Result;
|
||||||
@ -998,11 +1012,8 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) {
|
|||||||
case Instruction::FNeg:
|
case Instruction::FNeg:
|
||||||
return ConstantFP::get(C->getContext(), neg(CV));
|
return ConstantFP::get(C->getContext(), neg(CV));
|
||||||
}
|
}
|
||||||
} else if (VectorType *VTy = dyn_cast<VectorType>(C->getType())) {
|
} else if (auto *VTy = dyn_cast<FixedVectorType>(C->getType())) {
|
||||||
// Do not iterate on scalable vector. The number of elements is unknown at
|
|
||||||
// compile-time.
|
|
||||||
if (IsScalableVector)
|
|
||||||
return nullptr;
|
|
||||||
Type *Ty = IntegerType::get(VTy->getContext(), 32);
|
Type *Ty = IntegerType::get(VTy->getContext(), 32);
|
||||||
// Fast path for splatted constants.
|
// Fast path for splatted constants.
|
||||||
if (Constant *Splat = C->getSplatValue()) {
|
if (Constant *Splat = C->getSplatValue()) {
|
||||||
@ -1367,11 +1378,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
|
|||||||
return ConstantFP::get(C1->getContext(), C3V);
|
return ConstantFP::get(C1->getContext(), C3V);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
|
} else if (IsScalableVector) {
|
||||||
// Do not iterate on scalable vector. The number of elements is unknown at
|
// Do not iterate on scalable vector. The number of elements is unknown at
|
||||||
// compile-time.
|
// compile-time.
|
||||||
if (IsScalableVector)
|
// FIXME: this branch can potentially be removed
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (auto *VTy = dyn_cast<FixedVectorType>(C1->getType())) {
|
||||||
// Fast path for splatted constants.
|
// Fast path for splatted constants.
|
||||||
if (Constant *C2Splat = C2->getSplatValue()) {
|
if (Constant *C2Splat = C2->getSplatValue()) {
|
||||||
if (Instruction::isIntDivRem(Opcode) && C2Splat->isNullValue())
|
if (Instruction::isIntDivRem(Opcode) && C2Splat->isNullValue())
|
||||||
@ -2014,7 +2026,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
|
|||||||
SmallVector<Constant*, 4> ResElts;
|
SmallVector<Constant*, 4> ResElts;
|
||||||
Type *Ty = IntegerType::get(C1->getContext(), 32);
|
Type *Ty = IntegerType::get(C1->getContext(), 32);
|
||||||
// Compare the elements, producing an i1 result or constant expr.
|
// Compare the elements, producing an i1 result or constant expr.
|
||||||
for (unsigned i = 0, e = C1VTy->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = C1VTy->getElementCount().Min; i != e; ++i) {
|
||||||
Constant *C1E =
|
Constant *C1E =
|
||||||
ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
|
ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
|
||||||
Constant *C2E =
|
Constant *C2E =
|
||||||
@ -2286,14 +2298,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
|
|||||||
assert(Ty && "Invalid indices for GEP!");
|
assert(Ty && "Invalid indices for GEP!");
|
||||||
Type *OrigGEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
|
Type *OrigGEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
|
||||||
Type *GEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
|
Type *GEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
|
||||||
if (VectorType *VT = dyn_cast<VectorType>(C->getType()))
|
if (VectorType *VT = dyn_cast<VectorType>(C->getType())) {
|
||||||
GEPTy = FixedVectorType::get(OrigGEPTy, VT->getNumElements());
|
// FIXME: handle scalable vectors (use getElementCount())
|
||||||
|
GEPTy = FixedVectorType::get(
|
||||||
|
OrigGEPTy, cast<FixedVectorType>(VT)->getNumElements());
|
||||||
|
}
|
||||||
// The GEP returns a vector of pointers when one of more of
|
// The GEP returns a vector of pointers when one of more of
|
||||||
// its arguments is a vector.
|
// its arguments is a vector.
|
||||||
for (unsigned i = 0, e = Idxs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Idxs.size(); i != e; ++i) {
|
||||||
if (auto *VT = dyn_cast<VectorType>(Idxs[i]->getType())) {
|
if (auto *VT = dyn_cast<VectorType>(Idxs[i]->getType())) {
|
||||||
GEPTy = FixedVectorType::get(OrigGEPTy, VT->getNumElements());
|
// FIXME: handle scalable vectors
|
||||||
|
GEPTy = FixedVectorType::get(
|
||||||
|
OrigGEPTy, cast<FixedVectorType>(VT)->getNumElements());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2500,19 +2516,19 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
|
|||||||
|
|
||||||
if (!IsCurrIdxVector && IsPrevIdxVector)
|
if (!IsCurrIdxVector && IsPrevIdxVector)
|
||||||
CurrIdx = ConstantDataVector::getSplat(
|
CurrIdx = ConstantDataVector::getSplat(
|
||||||
cast<VectorType>(PrevIdx->getType())->getNumElements(), CurrIdx);
|
cast<FixedVectorType>(PrevIdx->getType())->getNumElements(), CurrIdx);
|
||||||
|
|
||||||
if (!IsPrevIdxVector && IsCurrIdxVector)
|
if (!IsPrevIdxVector && IsCurrIdxVector)
|
||||||
PrevIdx = ConstantDataVector::getSplat(
|
PrevIdx = ConstantDataVector::getSplat(
|
||||||
cast<VectorType>(CurrIdx->getType())->getNumElements(), PrevIdx);
|
cast<FixedVectorType>(CurrIdx->getType())->getNumElements(), PrevIdx);
|
||||||
|
|
||||||
Constant *Factor =
|
Constant *Factor =
|
||||||
ConstantInt::get(CurrIdx->getType()->getScalarType(), NumElements);
|
ConstantInt::get(CurrIdx->getType()->getScalarType(), NumElements);
|
||||||
if (UseVector)
|
if (UseVector)
|
||||||
Factor = ConstantDataVector::getSplat(
|
Factor = ConstantDataVector::getSplat(
|
||||||
IsPrevIdxVector
|
IsPrevIdxVector
|
||||||
? cast<VectorType>(PrevIdx->getType())->getNumElements()
|
? cast<FixedVectorType>(PrevIdx->getType())->getNumElements()
|
||||||
: cast<VectorType>(CurrIdx->getType())->getNumElements(),
|
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements(),
|
||||||
Factor);
|
Factor);
|
||||||
|
|
||||||
NewIdxs[i] = ConstantExpr::getSRem(CurrIdx, Factor);
|
NewIdxs[i] = ConstantExpr::getSRem(CurrIdx, Factor);
|
||||||
@ -2531,8 +2547,8 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
|
|||||||
ExtendedTy = FixedVectorType::get(
|
ExtendedTy = FixedVectorType::get(
|
||||||
ExtendedTy,
|
ExtendedTy,
|
||||||
IsPrevIdxVector
|
IsPrevIdxVector
|
||||||
? cast<VectorType>(PrevIdx->getType())->getNumElements()
|
? cast<FixedVectorType>(PrevIdx->getType())->getNumElements()
|
||||||
: cast<VectorType>(CurrIdx->getType())->getNumElements());
|
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements());
|
||||||
|
|
||||||
if (!PrevIdx->getType()->isIntOrIntVectorTy(CommonExtendedWidth))
|
if (!PrevIdx->getType()->isIntOrIntVectorTy(CommonExtendedWidth))
|
||||||
PrevIdx = ConstantExpr::getSExt(PrevIdx, ExtendedTy);
|
PrevIdx = ConstantExpr::getSExt(PrevIdx, ExtendedTy);
|
||||||
|
13
test/Analysis/ConstantFolding/extractelement-vscale.ll
Normal file
13
test/Analysis/ConstantFolding/extractelement-vscale.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; RUN: opt -instcombine -S < %s | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-LABEL: definitely_in_bounds
|
||||||
|
; CHECK: ret i8 0
|
||||||
|
define i8 @definitely_in_bounds() {
|
||||||
|
ret i8 extractelement (<vscale x 16 x i8> zeroinitializer, i64 15)
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: maybe_in_bounds
|
||||||
|
; CHECK: ret i8 extractelement (<vscale x 16 x i8> zeroinitializer, i64 16)
|
||||||
|
define i8 @maybe_in_bounds() {
|
||||||
|
ret i8 extractelement (<vscale x 16 x i8> zeroinitializer, i64 16)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user