diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-02-26 15:18:49 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-02-26 15:18:49 +0000 |
commit | e8bf0f79bdb60b30b00e15712b786eb5ce990c7a (patch) | |
tree | ea7095c6cb8be5d0d03b13191471110be9ec0ff4 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | c9af54bb554fe459795fe61eed169528e00b0910 (diff) | |
download | bcm5719-llvm-e8bf0f79bdb60b30b00e15712b786eb5ce990c7a.tar.gz bcm5719-llvm-e8bf0f79bdb60b30b00e15712b786eb5ce990c7a.zip |
[InstCombine] canonicalize more unsigned saturated add with 'not'
Yet another pattern variation suggested by:
https://bugs.llvm.org/show_bug.cgi?id=14613
There are 8 more potential commuted patterns here on top of the
8 that were already handled (rL354221, rL354276, rL354393).
We have the obvious commute of the 'add' + commute of the cmp
predicate/operands (ugt/ult) + commute of the select operands:
Name: base
%notx = xor i32 %x, -1
%a = add i32 %notx, %y
%c = icmp ult i32 %x, %y
%r = select i1 %c, i32 -1, i32 %a
=>
%c2 = icmp ult i32 %a, %y
%r = select i1 %c2, i32 -1, i32 %a
Name: ugt
%notx = xor i32 %x, -1
%a = add i32 %notx, %y
%c = icmp ugt i32 %y, %x
%r = select i1 %c, i32 -1, i32 %a
=>
%c2 = icmp ult i32 %a, %y
%r = select i1 %c2, i32 -1, i32 %a
Name: commute select
%notx = xor i32 %x, -1
%a = add i32 %notx, %y
%c = icmp ult i32 %y, %x
%r = select i1 %c, i32 %a, i32 -1
=>
%c2 = icmp ult i32 %a, %y
%r = select i1 %c2, i32 -1, i32 %a
Name: ugt + commute select
%notx = xor i32 %x, -1
%a = add i32 %notx, %y
%c = icmp ugt i32 %x, %y
%r = select i1 %c, i32 %a, i32 -1
=>
%c2 = icmp ult i32 %a, %y
%r = select i1 %c2, i32 -1, i32 %a
https://rise4fun.com/Alive/den
llvm-svn: 354887
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index d153c848d38..79835ef9316 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -725,6 +725,17 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal, Value *NewCmp = Builder.CreateICmp(ICmpInst::ICMP_ULT, FVal, Y); return Builder.CreateSelect(NewCmp, TVal, FVal); } + // The 'not' op may be included in the sum but not the compare. + X = Cmp0; + Y = Cmp1; + if (match(FVal, m_c_Add(m_Not(m_Specific(X)), m_Specific(Y)))) { + // Change the comparison to use the sum (false value of the select). That is + // a canonical pattern match form for uadd.with.overflow: + // (X u< Y) ? -1 : (~X + Y) --> ((~X + Y) u< Y) ? -1 : (~X + Y) + // (X u< Y) ? -1 : (Y + ~X) --> ((Y + ~X) u< Y) ? -1 : (Y + ~X) + Value *NewCmp = Builder.CreateICmp(ICmpInst::ICMP_ULT, FVal, Y); + return Builder.CreateSelect(NewCmp, TVal, FVal); + } return nullptr; } |