diff options
author | Chuang-Yu Cheng <cycheng@multicorewareinc.com> | 2016-06-24 01:59:00 +0000 |
---|---|---|
committer | Chuang-Yu Cheng <cycheng@multicorewareinc.com> | 2016-06-24 01:59:00 +0000 |
commit | 68f7f1cf00a0405446fe765d2ed6e583a6e5947b (patch) | |
tree | 97a6dbe9c41b67e00d60c5faf2169dff11ae3def /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | b19924a425edc9ff045fd20c794a6ec9917ba824 (diff) | |
download | bcm5719-llvm-68f7f1cf00a0405446fe765d2ed6e583a6e5947b.tar.gz bcm5719-llvm-68f7f1cf00a0405446fe765d2ed6e583a6e5947b.zip |
Teaching SimplifyCFG to recognize the Or-Mask trick that InstCombine uses to
reduce the number of comparisons.
Specifically, InstCombine can turn:
(i == 5334 || i == 5335)
into:
((i | 1) == 5335)
SimplifyCFG was already able to detect the pattern:
(i == 5334 || i == 5335)
to:
((i & -2) == 5334)
This patch supersedes D21315 and resolves PR27555
(https://llvm.org/bugs/show_bug.cgi?id=27555).
Thanks to David and Chandler for the suggestions!
Author: Thomas Jablin (tjablin)
Reviewers: majnemer chandlerc halfdan cycheng
http://reviews.llvm.org/D21397
llvm-svn: 273639
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 43e823d601e..7c0f85c2ca1 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -461,6 +461,9 @@ private: QUERY( (y & ~mask = y) => ((x & ~mask = y) <=> (x = y OR x = (y | mask))) ); + QUERY( (y | mask = y) => + ((x | mask = y) <=> (x = y OR x = (y & ~mask))) + ); */ // Please note that each pattern must be a dual implication (<--> or @@ -503,6 +506,28 @@ private: } } + // Pattern match a special case: + /* + QUERY( (y | mask = y) => + ((x | mask = y) <=> (x = y OR x = (y & ~mask))) + ); + */ + if (match(ICI->getOperand(0), + m_Or(m_Value(RHSVal), m_APInt(RHSC)))) { + APInt Mask = *RHSC; + if (Mask.isPowerOf2() && (C->getValue() | Mask) == C->getValue()) { + // If we already have a value for the switch, it has to match! + if (!setValueOnce(RHSVal)) + return false; + + Vals.push_back(C); + Vals.push_back(ConstantInt::get(C->getContext(), + C->getValue() & ~Mask)); + UsedICmps++; + return true; + } + } + // If we already have a value for the switch, it has to match! if (!setValueOnce(ICI->getOperand(0))) return false; |