Skip to content

Commit

Permalink
[InstCombine] reduce more unsigned saturated add with 'not' op
Browse files Browse the repository at this point in the history
We want to use the sum in the icmp to allow matching with
m_UAddWithOverflow and eliminate the 'not'. This is discussed
in D51929 and is another step towards solving PR14613:
https://bugs.llvm.org/show_bug.cgi?id=14613

  Name: not op
  %notx = xor i32 %x, -1
  %a = add i32 %x, %y
  %c = icmp ult i32 %notx, %y
  %r = select i1 %c, i32 -1, i32 %a
  =>
  %a = add i32 %x, %y
  %c2 = icmp ult i32 %a, %y
  %r = select i1 %c2, i32 -1, i32 %a

  Name: not op ugt
  %notx = xor i32 %x, -1
  %a = add i32 %x, %y
  %c = icmp ugt i32 %y, %notx
  %r = select i1 %c, i32 -1, i32 %a
  =>
  %a = add i32 %x, %y
  %c2 = icmp ult i32 %a, %y
  %r = select i1 %c2, i32 -1, i32 %a

https://rise4fun.com/Alive/niom

(The matching here is still incomplete.)

llvm-svn: 354224
  • Loading branch information
rotateright committed Feb 17, 2019
1 parent db02293 commit b341ee7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
16 changes: 13 additions & 3 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Expand Up @@ -677,13 +677,23 @@ static Value *canonicalizeSaturatedSubtract(const ICmpInst *ICI,

static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
InstCombiner::BuilderTy &Builder) {
if (!Cmp->hasOneUse() || Cmp->getPredicate() != ICmpInst::ICMP_ULT)
if (!Cmp->hasOneUse())
return nullptr;

// Match unsigned saturated add of 2 variables with an unnecessary 'not'.
// TODO: There are more variations of this pattern.
// Canonicalize to 'ULT' to simplify matching below.
Value *Cmp0 = Cmp->getOperand(0);
Value *Cmp1 = Cmp->getOperand(1);
ICmpInst::Predicate Pred = Cmp->getPredicate();
if (Pred == ICmpInst::ICMP_UGT) {
Pred = ICmpInst::ICMP_ULT;
std::swap(Cmp0, Cmp1);
}

if (Pred != ICmpInst::ICMP_ULT)
return nullptr;

// Match unsigned saturated add of 2 variables with an unnecessary 'not'.
// TODO: There are more variations of this pattern.
Value *X, *Y;
if (match(TVal, m_AllOnes()) && match(Cmp0, m_Not(m_Value(X))) &&
match(FVal, m_c_Add(m_Specific(X), m_Value(Y))) && Y == Cmp1) {
Expand Down
16 changes: 7 additions & 9 deletions llvm/test/Transforms/InstCombine/saturating-add-sub.ll
Expand Up @@ -672,11 +672,10 @@ define i32 @uadd_sat_commute_add(i32 %xp, i32 %y) {
define i32 @uadd_sat_ugt(i32 %x, i32 %yp) {
; CHECK-LABEL: @uadd_sat_ugt(
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
; CHECK-NEXT: [[A:%.*]] = add i32 [[Y]], [[X]]
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Y]], [[NOTX]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 -1, i32 [[A]]
; CHECK-NEXT: ret i32 [[R]]
; CHECK-NEXT: [[A:%.*]] = add i32 [[Y]], [[X:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[Y]]
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[A]]
; CHECK-NEXT: ret i32 [[TMP2]]
;
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
%notx = xor i32 %x, -1
Expand All @@ -690,11 +689,10 @@ define i32 @uadd_sat_ugt_commute_add(i32 %xp, i32 %yp) {
; CHECK-LABEL: @uadd_sat_ugt_commute_add(
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
; CHECK-NEXT: [[X:%.*]] = srem i32 42, [[XP:%.*]]
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X]], -1
; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y]]
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Y]], [[NOTX]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 -1, i32 [[A]]
; CHECK-NEXT: ret i32 [[R]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[Y]]
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[A]]
; CHECK-NEXT: ret i32 [[TMP2]]
;
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
%x = srem i32 42, %xp ; thwart complexity-based-canonicalization
Expand Down

0 comments on commit b341ee7

Please sign in to comment.