[PATCH] D87465: [TargetLowering] Change SimplifyDemandedBits for XOR
Jay Foad via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 15 04:34:55 PDT 2021
foad updated this revision to Diff 330608.
foad added a comment.
Fix ISD::OR -> ISD::AND.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87465/new/
https://reviews.llvm.org/D87465
Files:
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/test/CodeGen/X86/2012-08-07-CmpISelBug.ll
Index: llvm/test/CodeGen/X86/2012-08-07-CmpISelBug.ll
===================================================================
--- llvm/test/CodeGen/X86/2012-08-07-CmpISelBug.ll
+++ llvm/test/CodeGen/X86/2012-08-07-CmpISelBug.ll
@@ -13,8 +13,8 @@
; CHECK-NEXT: leal 13(%rdi), %eax
; CHECK-NEXT: xorb $-14, %al
; CHECK-NEXT: addb $82, %al
-; CHECK-NEXT: movzbl %al, %eax
; CHECK-NEXT: testl %esi, %edi
+; CHECK-NEXT: movzbl %al, %eax
; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: cmovnel %eax, %ecx
; CHECK-NEXT: xorb $81, %cl
Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1345,29 +1345,38 @@
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, VT, Op0, Op1));
ConstantSDNode* C = isConstOrConstSplat(Op1, DemandedElts);
- if (C) {
- // If one side is a constant, and all of the set bits in the constant are
- // also known set on the other side, turn this into an AND, as we know
- // the bits will be cleared.
- // e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
- // NB: it is okay if more bits are known than are requested
- if (C->getAPIntValue() == Known2.One) {
- SDValue ANDC =
- TLO.DAG.getConstant(~C->getAPIntValue() & DemandedBits, dl, VT);
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT, Op0, ANDC));
- }
+ if (C && (Op0.getOpcode() == ISD::OR || Op0.getOpcode() == ISD::AND)) {
+ ConstantSDNode *C1 = isConstOrConstSplat(Op0.getOperand(1), DemandedElts);
+ if (C1) {
+ // (X | C) ^ C -> X & ~C
+ if (Op0.getOpcode() == ISD::OR &&
+ !((C->getAPIntValue() ^ C1->getAPIntValue()) & DemandedBits)) {
+ SDValue NOTC =
+ TLO.DAG.getConstant(~C->getAPIntValue() & DemandedBits, dl, VT);
+ return TLO.CombineTo(
+ Op, TLO.DAG.getNode(ISD::AND, dl, VT, Op0.getOperand(0), NOTC));
+ }
- // If the RHS is a constant, see if we can change it. Don't alter a -1
- // constant because that's a 'not' op, and that is better for combining
- // and codegen.
- if (!C->isAllOnesValue() &&
- DemandedBits.isSubsetOf(C->getAPIntValue())) {
- // We're flipping all demanded bits. Flip the undemanded bits too.
- SDValue New = TLO.DAG.getNOT(dl, Op0, VT);
- return TLO.CombineTo(Op, New);
+ // (X & ~C) ^ C -> X | C
+ // TODO do this for the non-constant case too? I.e. (X & Y) ^ Z -> X | Z
+ // when all demanded bits of Y and Z are known to be different
+ if (Op0.getOpcode() == ISD::AND &&
+ DemandedBits.isSubsetOf(C->getAPIntValue() ^ C1->getAPIntValue()))
+ return TLO.CombineTo(
+ Op, TLO.DAG.getNode(ISD::AND, dl, VT, Op0.getOperand(0), Op1));
}
}
+ // If the RHS is a constant, see if we can change it. Don't alter a -1
+ // constant because that's a 'not' op, and that is better for combining
+ // and codegen.
+ if (C && !C->isAllOnesValue() &&
+ DemandedBits.isSubsetOf(C->getAPIntValue())) {
+ // We're flipping all demanded bits. Flip the undemanded bits too.
+ SDValue New = TLO.DAG.getNOT(dl, Op0, VT);
+ return TLO.CombineTo(Op, New);
+ }
+
// If we can't turn this into a 'not', try to shrink the constant.
if (!C || !C->isAllOnesValue())
if (ShrinkDemandedConstant(Op, DemandedBits, DemandedElts, TLO))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87465.330608.patch
Type: text/x-patch
Size: 3598 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210315/1dab85e3/attachment.bin>
More information about the llvm-commits
mailing list