[PATCH] D131955: [InstSimplify] Remove and(x.c) if all the known bits are handled just by x or c
Simon Pilgrim via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 16 04:26:09 PDT 2022
RKSimon created this revision.
RKSimon added reviewers: spatel, nikic.
Herald added a subscriber: hiraditya.
Herald added a project: All.
RKSimon requested review of this revision.
Herald added a project: LLVM.
This is a cut down version of what SimplifyMultipleUseDemandedBits tries to - if the RHS is a constant mask then see if the LHS known bits means that result bits are all known.
I wasn't sure how much we should be calling computeKnownBits in a lighter pass such as InstSimplify so I didn't generalise this to call computeKnownBits for a non-constant RHS as well, but we could very easily in the future, we could even consider moving InstCombinerImpl::SimplifyMultipleUseDemandedBits into InstSimplify?
Noticed as @spatel wondered if extending D131838 <https://reviews.llvm.org/D131838> test coverage would be easier in InstSimplify
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D131955
Files:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/AndOrXor.ll
Index: llvm/test/Transforms/InstSimplify/AndOrXor.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/AndOrXor.ll
+++ llvm/test/Transforms/InstSimplify/AndOrXor.ll
@@ -1106,8 +1106,7 @@
; 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
@@ -1118,8 +1117,7 @@
; 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
@@ -1130,10 +1128,7 @@
; hidden simplifydemandedbits constant.
define i8 @noop_and_t2(i8 %x) {
; CHECK-LABEL: @noop_and_t2(
-; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 2
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 127
-; CHECK-NEXT: [[C:%.*]] = and i8 [[B]], 62
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 62
;
%a = and i8 %x, 2
%b = or i8 %a, 127
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2043,21 +2043,18 @@
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.
+ // If all of the demanded bits are known 1 on one side, return the other.
+ // These bits cannot contribute to the result of the 'and' in this
+ // context.
+ // TODO: Generalize this for Op1 KnownBits?
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).isZero())
- 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).isZero())
+ KnownBits Known0 = computeKnownBits(Op0, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if ((Known0.Zero | *Mask).isAllOnes())
return Op0;
+ if ((Known0.One | ~*Mask).isAllOnes())
+ return Op1;
}
// If we have a multiplication overflow check that is being 'and'ed with a
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131955.452950.patch
Type: text/x-patch
Size: 2628 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220816/de54fd46/attachment.bin>
More information about the llvm-commits
mailing list