Skip to content

Commit 14f0289

Browse files
author
Nimit Sachdeva
committed
Change to APInt for scalar and splat vector
1 parent 945c0ca commit 14f0289

File tree

1 file changed

+49
-101
lines changed

1 file changed

+49
-101
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 49 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,120 +2006,68 @@ Value *InstCombinerImpl::foldSelectWithConstOpToBinOp(ICmpInst *Cmp,
20062006
static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
20072007
SelectInst &SI, ICmpInst *ICI, InstCombiner::BuilderTy &Builder) {
20082008
auto *CI = dyn_cast<ICmpInst>(SI.getCondition());
2009-
if (!CI) {
2009+
if (!CI)
20102010
return nullptr;
2011-
}
20122011

20132012
Value *CmpLHS = CI->getOperand(0);
20142013
Value *CmpRHS = CI->getOperand(1);
2015-
if (!match(CmpRHS, m_Zero())) {
2014+
if (!match(CmpRHS, m_Zero()))
20162015
return nullptr;
2017-
}
2018-
auto Pred = CI->getPredicate();
2019-
auto *TrueVal = SI.getTrueValue();
2020-
auto *FalseVal = SI.getFalseValue();
20212016

2022-
if (Pred != ICmpInst::ICMP_EQ && Pred != llvm::ICmpInst::ICMP_NE)
2017+
auto Pred = CI->getPredicate();
2018+
if (Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE)
20232019
return nullptr;
20242020

2025-
// Match: icmp eq (or (usub.sat A, IntConst1), (usub.sat B, IntConst2)), 0
20262021
Value *A, *B;
2027-
ConstantInt *IntConst1, *IntConst2, *PossibleMSBInt;
2028-
2029-
if (match(CmpLHS, m_Or(m_Intrinsic<Intrinsic::usub_sat>(
2030-
m_Value(A), m_ConstantInt(IntConst1)),
2031-
m_Intrinsic<Intrinsic::usub_sat>(
2032-
m_Value(B), m_ConstantInt(IntConst2)))) &&
2033-
(match(TrueVal, m_Zero()) &&
2034-
match(FalseVal, m_ConstantInt(PossibleMSBInt)) ||
2035-
match(TrueVal, m_ConstantInt(PossibleMSBInt)) &&
2036-
match(FalseVal, m_Zero()))) {
2037-
auto *Ty = A->getType();
2038-
unsigned BW = Ty->getIntegerBitWidth();
2039-
APInt MostSignificantBit = APInt::getOneBitSet(BW, BW - 1);
2040-
2041-
if (PossibleMSBInt->getValue() != MostSignificantBit)
2042-
return nullptr;
2043-
// Ensure IntConst1 and IntConst2 are >= MostSignificantBit
2044-
if (IntConst1->getValue().ult(MostSignificantBit) ||
2045-
IntConst2->getValue().ult(MostSignificantBit))
2046-
return nullptr;
2022+
const APInt *Constant1, *Constant2, *PossibleMSB;
2023+
if (!match(CmpLHS, m_Or(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A),
2024+
m_APInt(Constant1)),
2025+
m_Intrinsic<Intrinsic::usub_sat>(
2026+
m_Value(B), m_APInt(Constant2)))))
2027+
return nullptr;
20472028

2048-
// Rewrite:
2049-
Value *NewA = Builder.CreateBinaryIntrinsic(
2050-
Intrinsic::usub_sat, A,
2051-
ConstantInt::get(Ty, IntConst1->getValue() - MostSignificantBit + 1));
2052-
Value *NewB = Builder.CreateBinaryIntrinsic(
2053-
Intrinsic::usub_sat, B,
2054-
ConstantInt::get(Ty, IntConst2->getValue() - MostSignificantBit + 1));
2055-
Value *Or = Builder.CreateOr(NewA, NewB);
2056-
Value *And =
2057-
Builder.CreateAnd(Or, ConstantInt::get(Ty, MostSignificantBit));
2058-
return cast<Instruction>(And);
2059-
}
2060-
Constant *Const1, *Const2, *PossibleMSB;
2061-
if (match(CmpLHS, m_Or(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A),
2062-
m_Constant(Const1)),
2063-
m_Intrinsic<Intrinsic::usub_sat>(
2064-
m_Value(B), m_Constant(Const2)))) &&
2065-
(match(TrueVal, m_Zero()) && match(FalseVal, m_Constant(PossibleMSB))
2066-
|| match(TrueVal, m_Constant(PossibleMSB) ) && match(FalseVal, m_Zero()))) {
2067-
auto *VecTy1 = dyn_cast<FixedVectorType>(Const1->getType());
2068-
auto *VecTy2 = dyn_cast<FixedVectorType>(Const2->getType());
2069-
auto *VecTyMSB = dyn_cast<FixedVectorType>(PossibleMSB->getType());
2070-
if (!VecTy1 || !VecTy2 || !VecTyMSB) {
2071-
return nullptr;
2072-
}
2029+
Value *TrueVal = SI.getTrueValue();
2030+
Value *FalseVal = SI.getFalseValue();
2031+
if (!((match(TrueVal, m_Zero()) && match(FalseVal, m_APInt(PossibleMSB))) ||
2032+
(match(TrueVal, m_APInt(PossibleMSB)) && match(FalseVal, m_Zero()))))
2033+
return nullptr;
20732034

2074-
unsigned NumElements = VecTy1->getNumElements();
2035+
auto *Ty = A->getType();
2036+
auto *VecTy = dyn_cast<VectorType>(Ty);
2037+
unsigned BW = PossibleMSB->getBitWidth();
2038+
APInt MostSignificantBit = APInt::getOneBitSet(BW, BW - 1);
20752039

2076-
if (NumElements != VecTy2->getNumElements() ||
2077-
NumElements != VecTyMSB->getNumElements() || NumElements == 0) {
2078-
return nullptr;
2079-
}
2080-
auto *SplatMSB =
2081-
dyn_cast<ConstantInt>(PossibleMSB->getAggregateElement(0u));
2082-
unsigned BW = SplatMSB->getValue().getBitWidth();
2083-
APInt MostSignificantBit = APInt::getOneBitSet(BW, BW - 1);
2084-
if (!SplatMSB || SplatMSB->getValue() != MostSignificantBit) {
2085-
return nullptr;
2086-
}
2087-
for (unsigned int i = 1; i < NumElements; ++i) {
2088-
auto *Element =
2089-
dyn_cast<ConstantInt>(PossibleMSB->getAggregateElement(i));
2090-
if (!Element || Element->getValue() != SplatMSB->getValue()) {
2091-
return nullptr;
2092-
}
2093-
}
2094-
SmallVector<Constant *, 16> Arg1, Arg2;
2095-
for (unsigned int i = 0; i < NumElements; ++i) {
2096-
auto *E1 = dyn_cast<ConstantInt>(Const1->getAggregateElement(i));
2097-
auto *E2 = dyn_cast<ConstantInt>(Const2->getAggregateElement(i));
2098-
if (!E1 || !E2) {
2099-
return nullptr;
2100-
}
2101-
if (E1->getValue().ult(SplatMSB->getValue()) ||
2102-
E2->getValue().ult(SplatMSB->getValue())) {
2103-
return nullptr;
2104-
}
2105-
Arg1.emplace_back(
2106-
ConstantInt::get(A->getType()->getScalarType(),
2107-
E1->getValue() - MostSignificantBit + 1));
2108-
Arg2.emplace_back(
2109-
ConstantInt::get(B->getType()->getScalarType(),
2110-
E2->getValue() - MostSignificantBit + 1));
2111-
}
2112-
Constant *ConstVec1 = ConstantVector::get(Arg1);
2113-
Constant *ConstVec2 = ConstantVector::get(Arg2);
2114-
Value *NewA =
2115-
Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, ConstVec1);
2116-
Value *NewB =
2117-
Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, B, ConstVec2);
2118-
Value *Or = Builder.CreateOr(NewA, NewB);
2119-
Value *And = Builder.CreateAnd(Or, PossibleMSB);
2120-
return cast<Instruction>(And);
2040+
if (*PossibleMSB != MostSignificantBit ||
2041+
Constant1->ult(MostSignificantBit) || Constant2->ult(MostSignificantBit))
2042+
return nullptr;
2043+
2044+
APInt AdjAP1 = *Constant1 - MostSignificantBit + 1;
2045+
APInt AdjAP2 = *Constant2 - MostSignificantBit + 1;
2046+
2047+
Constant *Adj1, *Adj2;
2048+
if (VecTy) {
2049+
Constant *Elt1 = ConstantInt::get(VecTy->getElementType(), AdjAP1);
2050+
Constant *Elt2 = ConstantInt::get(VecTy->getElementType(), AdjAP2);
2051+
Adj1 = ConstantVector::getSplat(VecTy->getElementCount(), Elt1);
2052+
Adj2 = ConstantVector::getSplat(VecTy->getElementCount(), Elt2);
2053+
} else {
2054+
Adj1 = ConstantInt::get(Ty, AdjAP1);
2055+
Adj2 = ConstantInt::get(Ty, AdjAP2);
21212056
}
2122-
return nullptr;
2057+
2058+
Value *NewA = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, Adj1);
2059+
Value *NewB = Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, B, Adj2);
2060+
Value *Or = Builder.CreateOr(NewA, NewB);
2061+
Constant *MSBConst;
2062+
if (VecTy) {
2063+
MSBConst = ConstantVector::getSplat(
2064+
VecTy->getElementCount(),
2065+
ConstantInt::get(VecTy->getScalarType(), *PossibleMSB));
2066+
} else {
2067+
MSBConst = ConstantInt::get(Ty->getScalarType(), *PossibleMSB);
2068+
}
2069+
Value *And = Builder.CreateAnd(Or, MSBConst);
2070+
return cast<Instruction>(And);
21232071
}
21242072

21252073
/// Visit a SelectInst that has an ICmpInst as its first operand.

0 commit comments

Comments
 (0)