Skip to content

Commit

Permalink
[DAG] Move "xor (X logical_shift ShiftC), XorC --> (not X) logical_sh…
Browse files Browse the repository at this point in the history
…ift ShiftC" fold into SimplifyDemandedBits

SimplifyDemandedBits is called slightly later which allows the not(sext(x)) -> sext(not(x)) fold to occur via foldLogicOfShifts

As mentioned on D127115, we should be able to further generalise this based off the demanded bits.
  • Loading branch information
RKSimon committed Jul 15, 2022
1 parent 2d93326 commit 3c8bf29
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 25 deletions.
22 changes: 0 additions & 22 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Expand Up @@ -8488,28 +8488,6 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
return DAG.getNode(ISD::AND, DL, VT, NotX, N1);
}

if ((N0Opcode == ISD::SRL || N0Opcode == ISD::SHL) && N0.hasOneUse()) {
ConstantSDNode *XorC = isConstOrConstSplat(N1);
ConstantSDNode *ShiftC = isConstOrConstSplat(N0.getOperand(1));
unsigned BitWidth = VT.getScalarSizeInBits();
if (XorC && ShiftC) {
// Don't crash on an oversized shift. We can not guarantee that a bogus
// shift has been simplified to undef.
uint64_t ShiftAmt = ShiftC->getLimitedValue();
if (ShiftAmt < BitWidth) {
APInt Ones = APInt::getAllOnes(BitWidth);
Ones = N0Opcode == ISD::SHL ? Ones.shl(ShiftAmt) : Ones.lshr(ShiftAmt);
if (XorC->getAPIntValue() == Ones) {
// If the xor constant is a shifted -1, do a 'not' before the shift:
// xor (X << ShiftC), XorC --> (not X) << ShiftC
// xor (X >> ShiftC), XorC --> (not X) >> ShiftC
SDValue Not = DAG.getNOT(DL, N0.getOperand(0), VT);
return DAG.getNode(N0Opcode, DL, VT, Not, N0.getOperand(1));
}
}
}
}

// fold Y = sra (X, size(X)-1); xor (add (X, Y), Y) -> (abs X)
if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
SDValue A = N0Opcode == ISD::ADD ? N0 : N1;
Expand Down
26 changes: 25 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Expand Up @@ -1500,7 +1500,7 @@ bool TargetLowering::SimplifyDemandedBits(
if (DemandedBits.isSubsetOf(Known.Zero | Known2.Zero))
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, VT, Op0, Op1));

ConstantSDNode* C = isConstOrConstSplat(Op1, DemandedElts);
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
Expand All @@ -1521,6 +1521,30 @@ bool TargetLowering::SimplifyDemandedBits(
SDValue New = TLO.DAG.getNOT(dl, Op0, VT);
return TLO.CombineTo(Op, New);
}

unsigned Op0Opcode = Op0.getOpcode();
if ((Op0Opcode == ISD::SRL || Op0Opcode == ISD::SHL) && Op0.hasOneUse()) {
if (ConstantSDNode *ShiftC =
isConstOrConstSplat(Op0.getOperand(1), DemandedElts)) {
// Don't crash on an oversized shift. We can not guarantee that a
// bogus shift has been simplified to undef.
if (ShiftC->getAPIntValue().ult(BitWidth)) {
uint64_t ShiftAmt = ShiftC->getZExtValue();
APInt Ones = APInt::getAllOnes(BitWidth);
Ones = Op0Opcode == ISD::SHL ? Ones.shl(ShiftAmt)
: Ones.lshr(ShiftAmt);
if (C->getAPIntValue() == Ones) {
// If the xor constant is a shifted -1, do a 'not' before the
// shift:
// xor (X << ShiftC), XorC --> (not X) << ShiftC
// xor (X >> ShiftC), XorC --> (not X) >> ShiftC
SDValue Not = TLO.DAG.getNOT(dl, Op0.getOperand(0), VT);
return TLO.CombineTo(Op, TLO.DAG.getNode(Op0Opcode, dl, VT, Not,
Op0.getOperand(1)));
}
}
}
}
}

// If we can't turn this into a 'not', try to shrink the constant.
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/xor.ll
Expand Up @@ -464,16 +464,16 @@ define ptr @test12(ptr %op, i64 %osbot, i64 %intval) {
;
; X64-LIN-LABEL: test12:
; X64-LIN: # %bb.0:
; X64-LIN-NEXT: notl %edx
; X64-LIN-NEXT: movslq %edx, %rax
; X64-LIN-NEXT: notq %rax
; X64-LIN-NEXT: shlq $4, %rax
; X64-LIN-NEXT: addq %rdi, %rax
; X64-LIN-NEXT: retq
;
; X64-WIN-LABEL: test12:
; X64-WIN: # %bb.0:
; X64-WIN-NEXT: notl %r8d
; X64-WIN-NEXT: movslq %r8d, %rax
; X64-WIN-NEXT: notq %rax
; X64-WIN-NEXT: shlq $4, %rax
; X64-WIN-NEXT: addq %rcx, %rax
; X64-WIN-NEXT: retq
Expand Down

0 comments on commit 3c8bf29

Please sign in to comment.