[llvm] r342004 - [InstCombine] add folds for unsigned-overflow compares

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 11 15:40:20 PDT 2018


Author: spatel
Date: Tue Sep 11 15:40:20 2018
New Revision: 342004

URL: http://llvm.org/viewvc/llvm-project?rev=342004&view=rev
Log:
[InstCombine] add folds for unsigned-overflow compares

Name: op_ugt_sum
  %a = add i8 %x, %y
  %r = icmp ugt i8 %x, %a
  =>
  %notx = xor i8 %x, -1
  %r = icmp ugt i8 %y, %notx

Name: sum_ult_op
  %a = add i8 %x, %y
  %r = icmp ult i8 %a, %x
  =>
  %notx = xor i8 %x, -1
  %r = icmp ugt i8 %y, %notx

https://rise4fun.com/Alive/ZRxI

AFAICT, this doesn't interfere with any add-saturation patterns
because those have >1 use for the 'add'. But this should be
better for IR analysis and codegen in the basic cases.

This is another fold inspired by PR14613:
https://bugs.llvm.org/show_bug.cgi?id=14613

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/icmp-add.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=342004&r1=342003&r2=342004&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue Sep 11 15:40:20 2018
@@ -3047,6 +3047,18 @@ Instruction *InstCombiner::foldICmpBinOp
     return nullptr;
 
   const CmpInst::Predicate Pred = I.getPredicate();
+  Value *X;
+
+  // Convert add-with-unsigned-overflow comparisons into a 'not' with compare.
+  // (Op1 + X) <u Op1 --> ~Op1 <u X
+  // Op0 >u (Op0 + X) --> X >u ~Op0
+  if (match(Op0, m_OneUse(m_c_Add(m_Specific(Op1), m_Value(X)))) &&
+      Pred == ICmpInst::ICMP_ULT)
+    return new ICmpInst(Pred, Builder.CreateNot(Op1), X);
+  if (match(Op1, m_OneUse(m_c_Add(m_Specific(Op0), m_Value(X)))) &&
+      Pred == ICmpInst::ICMP_UGT)
+    return new ICmpInst(Pred, X, Builder.CreateNot(Op0));
+
   bool NoOp0WrapProblem = false, NoOp1WrapProblem = false;
   if (BO0 && isa<OverflowingBinaryOperator>(BO0))
     NoOp0WrapProblem =

Modified: llvm/trunk/test/Transforms/InstCombine/icmp-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-add.ll?rev=342004&r1=342003&r2=342004&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp-add.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp-add.ll Tue Sep 11 15:40:20 2018
@@ -377,8 +377,8 @@ define i1 @op_ugt_sum_commute1(i8 %p1, i
 ; CHECK-LABEL: @op_ugt_sum_commute1(
 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], [[Y]]
-; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %x = sdiv i8 42, %p1
@@ -392,8 +392,8 @@ define <2 x i1> @op_ugt_sum_vec_commute2
 ; CHECK-LABEL: @op_ugt_sum_vec_commute2(
 ; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
 ; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P2:%.*]]
-; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[Y]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[X]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
@@ -424,8 +424,8 @@ define <2 x i1> @sum_ult_op_vec_commute1
 ; CHECK-LABEL: @sum_ult_op_vec_commute1(
 ; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
 ; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 -42, i8 42>, [[P2:%.*]]
-; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X]], [[Y]]
-; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> [[A]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
@@ -439,8 +439,8 @@ define i1 @sum_ult_op_commute2(i8 %p1, i
 ; CHECK-LABEL: @sum_ult_op_commute2(
 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %x = sdiv i8 42, %p1




More information about the llvm-commits mailing list