[llvm] 79bb915 - [InstCombine] enhance fold for subtract-from-constant -> xor

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 8 07:11:30 PDT 2022


Author: Sanjay Patel
Date: 2022-07-08T10:02:19-04:00
New Revision: 79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd

URL: https://github.com/llvm/llvm-project/commit/79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd
DIFF: https://github.com/llvm/llvm-project/commit/79bb915fb60b2cd220d89e3bb54f67abb8cdb7bd.diff

LOG: [InstCombine] enhance fold for subtract-from-constant -> xor

A low-bit mask is not required:
https://alive2.llvm.org/ce/z/yPShss

This matches the SDAG implementation that was updated at:
8b756713140f

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/sub-xor.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index f53cce10f61e5..01821a71be4d2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1965,14 +1965,12 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
       return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
   }
 
+  // If there's no chance any bit will need to borrow from an adjacent bit:
+  // sub C, X --> xor X, C
   const APInt *Op0C;
-  if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) {
-    // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
-    // zero.
-    KnownBits RHSKnown = computeKnownBits(Op1, 0, &I);
-    if ((*Op0C | RHSKnown.Zero).isAllOnes())
-      return BinaryOperator::CreateXor(Op1, Op0);
-  }
+  if (match(Op0, m_APInt(Op0C)) &&
+      (~computeKnownBits(Op1, 0, &I).Zero).isSubsetOf(*Op0C))
+    return BinaryOperator::CreateXor(Op1, Op0);
 
   {
     Value *Y;

diff  --git a/llvm/test/Transforms/InstCombine/sub-xor.ll b/llvm/test/Transforms/InstCombine/sub-xor.ll
index 388fa920b0cf6..f47bc2fdae7e9 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor.ll
@@ -28,7 +28,7 @@ define <2 x i32> @test1vec(<2 x i32> %x) {
 define i8 @masked_sub_i8(i8 %x) {
 ; CHECK-LABEL: @masked_sub_i8(
 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X:%.*]], 10
-; CHECK-NEXT:    [[M:%.*]] = sub nuw nsw i8 11, [[A]]
+; CHECK-NEXT:    [[M:%.*]] = xor i8 [[A]], 11
 ; CHECK-NEXT:    ret i8 [[M]]
 ;
   %a = and i8 %x, 10 ; 0b00001010
@@ -39,7 +39,7 @@ define i8 @masked_sub_i8(i8 %x) {
 define <2 x i5> @masked_sub_v2i5(<2 x i5> %x) {
 ; CHECK-LABEL: @masked_sub_v2i5(
 ; CHECK-NEXT:    [[A:%.*]] = and <2 x i5> [[X:%.*]], <i5 -8, i5 -8>
-; CHECK-NEXT:    [[M:%.*]] = sub nuw nsw <2 x i5> <i5 -6, i5 -6>, [[A]]
+; CHECK-NEXT:    [[M:%.*]] = xor <2 x i5> [[A]], <i5 -6, i5 -6>
 ; CHECK-NEXT:    ret <2 x i5> [[M]]
 ;
   %a = and <2 x i5> %x, <i5 24, i5 24> ; 0b11000
@@ -47,6 +47,8 @@ define <2 x i5> @masked_sub_v2i5(<2 x i5> %x) {
   ret <2 x i5> %m
 }
 
+; negative test - sub constant isn't superset of masked bits
+
 define i8 @not_masked_sub_i8(i8 %x) {
 ; CHECK-LABEL: @not_masked_sub_i8(
 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X:%.*]], 7


        


More information about the llvm-commits mailing list