diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-10-29 16:21:19 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-10-29 16:21:19 +0000 |
commit | 36eeb6d6f645176ddcec07616b1f7cea6fa8b555 (patch) | |
tree | fd9110d708da4b0f213bdde96d4900aa4fb60136 /llvm/lib/Analysis | |
parent | e9fa95e572166f04a093f2e26a2b4937e14d4048 (diff) | |
download | bcm5719-llvm-36eeb6d6f645176ddcec07616b1f7cea6fa8b555.tar.gz bcm5719-llvm-36eeb6d6f645176ddcec07616b1f7cea6fa8b555.zip |
[ValueTracking] recognize more variants of smin/smax
Try harder to detect obfuscated min/max patterns: the initial pattern was added with D9352 / rL236202.
There was a bug fix for PR27137 at rL264996, but I think we can do better by folding the corresponding
smax pattern and commuted variants.
The codegen tests demonstrate the effect of ValueTracking on the backend via SelectionDAGBuilder. We
can't expose these differences minimally in IR because we don't have smin/smax intrinsics for IR.
Differential Revision: https://reviews.llvm.org/D26091
llvm-svn: 285499
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index b99372a51fe..f1b91d2fbb5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3969,17 +3969,25 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, } } - // Y >s C ? ~Y : ~C == ~Y <s ~C ? ~Y : ~C = SMIN(~Y, ~C) + // (X >s C) ? ~X : ~C ==> (~X <s ~C) ? ~X : ~C ==> SMIN(~X, ~C) + // (X <s C) ? ~X : ~C ==> (~X >s ~C) ? ~X : ~C ==> SMAX(~X, ~C) const APInt *C2; - if (match(FalseVal, m_APInt(C2))) { - if (Pred == ICmpInst::ICMP_SGT && - CmpRHS->getType() == FalseVal->getType() && ~(*C1) == *C2 && - (match(TrueVal, m_Not(m_Specific(CmpLHS))) || - match(CmpLHS, m_Not(m_Specific(TrueVal))))) { - LHS = TrueVal; - RHS = FalseVal; - return {SPF_SMIN, SPNB_NA, false}; - } + if (match(TrueVal, m_Not(m_Specific(CmpLHS))) && + match(FalseVal, m_APInt(C2)) && ~(*C1) == *C2 && + (Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SLT)) { + LHS = TrueVal; + RHS = FalseVal; + return {Pred == CmpInst::ICMP_SGT ? SPF_SMIN : SPF_SMAX, SPNB_NA, false}; + } + + // (X >s C) ? ~C : ~X ==> (~X <s ~C) ? ~C : ~X ==> SMAX(~C, ~X) + // (X <s C) ? ~C : ~X ==> (~X >s ~C) ? ~C : ~X ==> SMIN(~C, ~X) + if (match(FalseVal, m_Not(m_Specific(CmpLHS))) && + match(TrueVal, m_APInt(C2)) && ~(*C1) == *C2 && + (Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SLT)) { + LHS = TrueVal; + RHS = FalseVal; + return {Pred == CmpInst::ICMP_SGT ? SPF_SMAX : SPF_SMIN, SPNB_NA, false}; } } |