diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 29 | 
2 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 3ddf182..cbaff29 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3997,6 +3997,27 @@ static Value *foldOrUnsignedUMulOverflowICmp(BinaryOperator &I,    return nullptr;  } +/// Fold select(X >s 0, 0, -X) | smax(X, 0) --> abs(X) +///      select(X <s 0, -X, 0) | smax(X, 0) --> abs(X) +static Value *FoldOrOfSelectSmaxToAbs(BinaryOperator &I, +                                      InstCombiner::BuilderTy &Builder) { +  Value *X; +  Value *Sel; +  if (match(&I, +            m_c_Or(m_Value(Sel), m_OneUse(m_SMax(m_Value(X), m_ZeroInt()))))) { +    auto NegX = m_Neg(m_Specific(X)); +    if (match(Sel, m_Select(m_SpecificICmp(ICmpInst::ICMP_SGT, m_Specific(X), +                                           m_ZeroInt()), +                            m_ZeroInt(), NegX)) || +        match(Sel, m_Select(m_SpecificICmp(ICmpInst::ICMP_SLT, m_Specific(X), +                                           m_ZeroInt()), +                            NegX, m_ZeroInt()))) +      return Builder.CreateBinaryIntrinsic(Intrinsic::abs, X, +                                           Builder.getFalse()); +  } +  return nullptr; +} +  // FIXME: We use commutative matchers (m_c_*) for some, but not all, matches  // here. We should standardize that construct where it is needed or choose some  // other way to ensure that commutated variants of patterns are not missed. @@ -4545,6 +4566,9 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {      if (Value *V = SimplifyAddWithRemainder(I))        return replaceInstUsesWith(I, V); +  if (Value *Res = FoldOrOfSelectSmaxToAbs(I, Builder)) +    return replaceInstUsesWith(I, Res); +    return nullptr;  } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index f5130da..9572f9d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3599,6 +3599,21 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {                                   m_Not(m_Specific(SelCond->getTrueValue())));        if (MayNeedFreeze)          C = Builder.CreateFreeze(C); +      if (!ProfcheckDisableMetadataFixes) { +        Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr; +        if (match(CondVal, m_LogicalAnd(m_Specific(C), m_Value(A2))) && +            SelCond) { +          return SelectInst::Create(C, A, B, "", nullptr, SelCond); +        } else if (match(FalseVal, +                         m_LogicalAnd(m_Not(m_Value(C2)), m_Value(B2))) && +                   SelFVal) { +          SelectInst *NewSI = SelectInst::Create(C, A, B, "", nullptr, SelFVal); +          NewSI->swapProfMetadata(); +          return NewSI; +        } else { +          return createSelectInstWithUnknownProfile(C, A, B); +        } +      }        return SelectInst::Create(C, A, B);      } @@ -3615,6 +3630,20 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {                                   m_Not(m_Specific(SelFVal->getTrueValue())));        if (MayNeedFreeze)          C = Builder.CreateFreeze(C); +      if (!ProfcheckDisableMetadataFixes) { +        Value *C2 = nullptr, *A2 = nullptr, *B2 = nullptr; +        if (match(CondVal, m_LogicalAnd(m_Not(m_Value(C2)), m_Value(A2))) && +            SelCond) { +          SelectInst *NewSI = SelectInst::Create(C, B, A, "", nullptr, SelCond); +          NewSI->swapProfMetadata(); +          return NewSI; +        } else if (match(FalseVal, m_LogicalAnd(m_Specific(C), m_Value(B2))) && +                   SelFVal) { +          return SelectInst::Create(C, B, A, "", nullptr, SelFVal); +        } else { +          return createSelectInstWithUnknownProfile(C, B, A); +        } +      }        return SelectInst::Create(C, B, A);      }    }  | 
