summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-10-29 16:21:19 +0000
committerSanjay Patel <spatel@rotateright.com>2016-10-29 16:21:19 +0000
commit36eeb6d6f645176ddcec07616b1f7cea6fa8b555 (patch)
treefd9110d708da4b0f213bdde96d4900aa4fb60136 /llvm/lib/Analysis
parente9fa95e572166f04a093f2e26a2b4937e14d4048 (diff)
downloadbcm5719-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.cpp28
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};
}
}
OpenPOWER on IntegriCloud