@@ -2006,120 +2006,68 @@ Value *InstCombinerImpl::foldSelectWithConstOpToBinOp(ICmpInst *Cmp,
20062006static 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