[llvm] [RISCV] Fold (X & (7 << 29)) == 0 -> (srliw X, 29) == 0 for RV64. (PR #156769)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 16:53:03 PDT 2025
================
@@ -16749,20 +16745,36 @@ static SDValue performSETCCCombine(SDNode *N,
combineVectorSizedSetCCEquality(VT, N0, N1, Cond, dl, DAG, Subtarget))
return V;
- // (X & -4096) == 0 -> (X >> 12) == 0 if the AND constant can't use ANDI.
if (DCI.isAfterLegalizeDAG() && isNullConstant(N1) &&
N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
isa<ConstantSDNode>(N0.getOperand(1))) {
const APInt &AndRHSC =
cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
+ // (X & -4096) == 0 -> (X >> 12) == 0 if the AND constant can't use ANDI.
if (!isInt<12>(AndRHSC.getSExtValue()) && AndRHSC.isNegatedPowerOf2()) {
unsigned ShiftBits = AndRHSC.countr_zero();
- SDValue Shift = DAG.getNode(ISD::SRL, dl, VT, N0.getOperand(0),
- DAG.getConstant(ShiftBits, dl, VT));
+ SDValue Shift = DAG.getNode(ISD::SRL, dl, OpVT, N0.getOperand(0),
+ DAG.getConstant(ShiftBits, dl, OpVT));
+ return DAG.getSetCC(dl, VT, Shift, N1, Cond);
+ }
+
+ // Similar to above but handling the lower 32 bits by using srliw.
+ // FIXME: Handle the case where N1 is non-zero.
+ if (OpVT == MVT::i64 && AndRHSC.getZExtValue() <= 0xffffffff &&
----------------
topperc wrote:
> And this happens to fold into a srlw because we only care about the zero-ness of the shift, so extending bit 31 is fine?
srliw is filling zeros to any bits in the result above the original bit 31. I'm not sure if that's what you mean by "extending bit 31"?. It would also be correct to use sraiw for this case which would duplicate the original bit 31.
> If so, can we generalize this by replacing the AND with a SHL to clear the high bits, and adjusting the SRL amount?
Yes
https://github.com/llvm/llvm-project/pull/156769
More information about the llvm-commits
mailing list