[llvm] f688ae7 - [InstCombine] allow vector splats for add+xor with low-mask

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 8 13:00:32 PDT 2020


Author: Sanjay Patel
Date: 2020-10-08T15:53:38-04:00
New Revision: f688ae7a0e91ccd6d4ba39103b68eef22534e51e

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

LOG: [InstCombine] allow vector splats for add+xor with low-mask

This can be allowed with undef elements too, but that can be another step:
https://alive2.llvm.org/ce/z/hnC4Z-

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 c53e4bc0e015..446085a3bdb3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -924,9 +924,19 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
       C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C)
     return CastInst::Create(Instruction::SExt, X, Ty);
 
-  // (X ^ signmask) + C --> (X + (signmask ^ C))
-  if (match(Op0, m_Xor(m_Value(X), m_APInt(C2))) && C2->isSignMask())
-    return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C));
+  if (match(Op0, m_Xor(m_Value(X), m_APInt(C2)))) {
+    // (X ^ signmask) + C --> (X + (signmask ^ C))
+    if (C2->isSignMask())
+      return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C));
+
+    // If X has no high-bits set above an xor mask:
+    // add (xor X, LowMaskC), C --> sub (LowMaskC + C), X
+    if (C2->isMask()) {
+      KnownBits LHSKnown = computeKnownBits(X, 0, &Add);
+      if ((*C2 | LHSKnown.Zero).isAllOnesValue())
+        return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *C), X);
+    }
+  }
 
   if (C->isOneValue() && Op0->hasOneUse()) {
     // add (sext i1 X), 1 --> zext (not X)
@@ -1295,15 +1305,6 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
         Value *NewShl = Builder.CreateShl(XorLHS, ShAmt, "sext");
         return BinaryOperator::CreateAShr(NewShl, ShAmt);
       }
-
-      // If X has no high-bits above the xor mask set:
-      // add (xor X, LowMaskC), C --> sub (LowMaskC + C), X
-      if ((XorRHS->getValue() + 1).isPowerOf2()) {
-        KnownBits LHSKnown = computeKnownBits(XorLHS, 0, &I);
-        if ((XorRHS->getValue() | LHSKnown.Zero).isAllOnesValue())
-          return BinaryOperator::CreateSub(ConstantExpr::getAdd(XorRHS, CI),
-                                           XorLHS);
-      }
     }
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/sub-xor.ll b/llvm/test/Transforms/InstCombine/sub-xor.ll
index 583a32ee3e48..cae292b21ad1 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor.ll
@@ -68,8 +68,7 @@ define i32 @xor_add_extra_use(i32 %x) {
 define <2 x i8> @xor_add_splat(<2 x i8> %x) {
 ; CHECK-LABEL: @xor_add_splat(
 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 24, i8 24>
-; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i8> [[AND]], <i8 63, i8 63>
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i8> [[XOR]], <i8 42, i8 42>
+; CHECK-NEXT:    [[ADD:%.*]] = sub nuw nsw <2 x i8> <i8 105, i8 105>, [[AND]]
 ; CHECK-NEXT:    ret <2 x i8> [[ADD]]
 ;
   %and = and <2 x i8> %x, <i8 24, i8 24>


        


More information about the llvm-commits mailing list