[llvm] ea1a0d7 - [InstSimplify] Bypass no-op `and`-mask, using known bits (PR49543)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 20 14:33:42 PDT 2021


Author: Roman Lebedev
Date: 2021-04-21T00:31:46+03:00
New Revision: ea1a0d7c9ae3e5232a4163fc67efad4aabd51f2b

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

LOG: [InstSimplify] Bypass no-op `and`-mask, using known bits (PR49543)

We already special-cased a few interesting patterns,
but that is strictly less powerful than using KnownBits.

So instead get the known bits for the operand of `and`,
and iff all the unset bits of the `and`-mask are known to be zeros
in the operand, we can omit said `and`.

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/AndOrXor.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 08f504a0ce37..43441184115f 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2081,21 +2081,12 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
   if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
     return V;
 
-  // A mask that only clears known zeros of a shifted value is a no-op.
+  // A mask that only clears known zeros of a value is a no-op.
   Value *X;
   const APInt *Mask;
-  const APInt *ShAmt;
   if (match(Op1, m_APInt(Mask))) {
-    // If all bits in the inverted and shifted mask are clear:
-    // and (shl X, ShAmt), Mask --> shl X, ShAmt
-    if (match(Op0, m_Shl(m_Value(X), m_APInt(ShAmt))) &&
-        (~(*Mask)).lshr(*ShAmt).isNullValue())
-      return Op0;
-
-    // If all bits in the inverted and shifted mask are clear:
-    // and (lshr X, ShAmt), Mask --> lshr X, ShAmt
-    if (match(Op0, m_LShr(m_Value(X), m_APInt(ShAmt))) &&
-        (~(*Mask)).shl(*ShAmt).isNullValue())
+    KnownBits Known = computeKnownBits(Op0, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+    if ((~*Mask).isSubsetOf(Known.Zero))
       return Op0;
   }
 
@@ -2180,6 +2171,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
   // SimplifyDemandedBits in InstCombine can optimize the general case.
   // This pattern aims to help other passes for a common case.
   Value *Y, *XShifted;
+  const APInt *ShAmt;
   if (match(Op1, m_APInt(Mask)) &&
       match(Op0, m_c_Or(m_CombineAnd(m_NUWShl(m_Value(X), m_APInt(ShAmt)),
                                      m_Value(XShifted)),

diff  --git a/llvm/test/Transforms/InstSimplify/AndOrXor.ll b/llvm/test/Transforms/InstSimplify/AndOrXor.ll
index ee94d2f7720e..09f6faf3928c 100644
--- a/llvm/test/Transforms/InstSimplify/AndOrXor.ll
+++ b/llvm/test/Transforms/InstSimplify/AndOrXor.ll
@@ -1192,8 +1192,7 @@ define i8 @noop_and_t0(i8 %x) {
 ; CHECK-LABEL: @noop_and_t0(
 ; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 3
 ; CHECK-NEXT:    [[B:%.*]] = lshr i8 [[A]], 2
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], 62
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[B]]
 ;
   %a = shl i8 %x, 3
   %b = lshr i8 %a, 2
@@ -1204,8 +1203,7 @@ define i8 @noop_and_t1(i8 %x) {
 ; CHECK-LABEL: @noop_and_t1(
 ; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 3
 ; CHECK-NEXT:    [[B:%.*]] = lshr i8 [[A]], 2
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], 126
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[B]]
 ;
   %a = shl i8 %x, 3
   %b = lshr i8 %a, 2


        


More information about the llvm-commits mailing list