[llvm] 412fc74 - [InstCombine] fold not+or+neg

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 2 10:16:58 PDT 2021


Author: Sanjay Patel
Date: 2021-04-02T13:16:36-04:00
New Revision: 412fc74140c01cc9c29245a248edeee59d8814a4

URL: https://github.com/llvm/llvm-project/commit/412fc74140c01cc9c29245a248edeee59d8814a4
DIFF: https://github.com/llvm/llvm-project/commit/412fc74140c01cc9c29245a248edeee59d8814a4.diff

LOG: [InstCombine] fold not+or+neg

~((-X) | Y) --> (X - 1) & (~Y)

We generally prefer 'add' over 'sub', this reduces the
dependency chain, and this looks better for codegen on
x86, ARM, and AArch64 targets.

https://llvm.org/PR45755

https://alive2.llvm.org/ce/z/cxZDSp

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/not.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b9147e978deb..5e7abebe48a7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3204,6 +3204,14 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
       if (isa<Constant>(X) || NotVal->hasOneUse())
         return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
 
+    // ~((-X) | Y) --> (X - 1) & (~Y)
+    if (match(NotVal,
+              m_OneUse(m_c_Or(m_OneUse(m_Neg(m_Value(X))), m_Value(Y))))) {
+      Value *DecX = Builder.CreateAdd(X, ConstantInt::getAllOnesValue(Ty));
+      Value *NotY = Builder.CreateNot(Y);
+      return BinaryOperator::CreateAnd(DecX, NotY);
+    }
+
     // ~(~X >>s Y) --> (X >>s Y)
     if (match(NotVal, m_AShr(m_Not(m_Value(X)), m_Value(Y))))
       return BinaryOperator::CreateAShr(X, Y);

diff  --git a/llvm/test/Transforms/InstCombine/not.ll b/llvm/test/Transforms/InstCombine/not.ll
index ff9b49462bf1..146fea71cd1c 100644
--- a/llvm/test/Transforms/InstCombine/not.ll
+++ b/llvm/test/Transforms/InstCombine/not.ll
@@ -408,9 +408,9 @@ define i1 @not_select_cmpf_extra_use(i1 %x, i32 %z, i32 %w, i1 %cond) {
 
 define i8 @not_or_neg(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @not_or_neg(
-; CHECK-NEXT:    [[S:%.*]] = sub i8 0, [[Y:%.*]]
-; CHECK-NEXT:    [[O:%.*]] = or i8 [[S]], [[X:%.*]]
-; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[O]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], -1
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT:    [[NOT:%.*]] = and i8 [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret i8 [[NOT]]
 ;
   %s = sub i8 0, %y
@@ -422,9 +422,9 @@ define i8 @not_or_neg(i8 %x, i8 %y)  {
 define <3 x i5> @not_or_neg_commute_vec(<3 x i5> %x, <3 x i5> %p)  {
 ; CHECK-LABEL: @not_or_neg_commute_vec(
 ; CHECK-NEXT:    [[Y:%.*]] = mul <3 x i5> [[P:%.*]], <i5 1, i5 2, i5 3>
-; CHECK-NEXT:    [[S:%.*]] = sub <3 x i5> <i5 0, i5 0, i5 undef>, [[X:%.*]]
-; CHECK-NEXT:    [[O:%.*]] = or <3 x i5> [[Y]], [[S]]
-; CHECK-NEXT:    [[NOT:%.*]] = xor <3 x i5> [[O]], <i5 -1, i5 undef, i5 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = add <3 x i5> [[X:%.*]], <i5 -1, i5 -1, i5 -1>
+; CHECK-NEXT:    [[TMP2:%.*]] = xor <3 x i5> [[Y]], <i5 -1, i5 -1, i5 -1>
+; CHECK-NEXT:    [[NOT:%.*]] = and <3 x i5> [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret <3 x i5> [[NOT]]
 ;
   %y = mul <3 x i5> %p, <i5 1, i5 2, i5 3> ; thwart complexity-based-canonicalization
@@ -434,6 +434,8 @@ define <3 x i5> @not_or_neg_commute_vec(<3 x i5> %x, <3 x i5> %p)  {
   ret <3 x i5> %not
 }
 
+; negative test
+
 define i8 @not_or_neg_use1(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @not_or_neg_use1(
 ; CHECK-NEXT:    [[S:%.*]] = sub i8 0, [[Y:%.*]]
@@ -449,6 +451,8 @@ define i8 @not_or_neg_use1(i8 %x, i8 %y)  {
   ret i8 %not
 }
 
+; negative test
+
 define i8 @not_or_neg_use2(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @not_or_neg_use2(
 ; CHECK-NEXT:    [[S:%.*]] = sub i8 0, [[Y:%.*]]


        


More information about the llvm-commits mailing list