Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16761,29 +16761,36 @@ static SDValue performSETCCCombine(SDNode *N,
combineVectorSizedSetCCEquality(VT, N0, N1, Cond, dl, DAG, Subtarget))
return V;

if (DCI.isAfterLegalizeDAG() && isNullConstant(N1) &&
if (DCI.isAfterLegalizeDAG() && isa<ConstantSDNode>(N1) &&
N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
isa<ConstantSDNode>(N0.getOperand(1))) {
const APInt &AndRHSC =
cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
const APInt &AndRHSC = N0.getConstantOperandAPInt(1);
// (X & -(1 << C)) == 0 -> (X >> C) == 0 if the AND constant can't use ANDI.
if (!isInt<12>(AndRHSC.getSExtValue()) && AndRHSC.isNegatedPowerOf2()) {
if (isNullConstant(N1) && !isInt<12>(AndRHSC.getSExtValue()) &&
AndRHSC.isNegatedPowerOf2()) {
unsigned ShiftBits = AndRHSC.countr_zero();
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.
// Similar to above but handling the lower 32 bits by using sraiw. Allow
// comparing with constants other than 0 if the constant can be folded into
// addi or xori after shifting.
if (OpVT == MVT::i64 && AndRHSC.getZExtValue() <= 0xffffffff &&
isPowerOf2_32(-uint32_t(AndRHSC.getZExtValue()))) {
unsigned ShiftBits = llvm::countr_zero(AndRHSC.getZExtValue());
SDValue And = DAG.getNode(ISD::AND, dl, OpVT, N0.getOperand(0),
DAG.getConstant(0xffffffff, dl, OpVT));
SDValue Shift = DAG.getNode(ISD::SRL, dl, OpVT, And,
DAG.getConstant(ShiftBits, dl, OpVT));
return DAG.getSetCC(dl, VT, Shift, N1, Cond);
int64_t NewC = SignExtend64<32>(cast<ConstantSDNode>(N1)->getSExtValue());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we discard bits 32-63 of N1. Don't we need to check them?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also discarded the shifted out bits, we need to check those too. N1 needs to be a subset of AndRHSC. Thanks for catching that.

NewC >>= ShiftBits;
if (isInt<12>(NewC) || NewC == 2048) {
SDValue SExt =
DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, OpVT, N0.getOperand(0),
DAG.getValueType(MVT::i32));
SDValue Shift = DAG.getNode(ISD::SRA, dl, OpVT, SExt,
DAG.getConstant(ShiftBits, dl, OpVT));
return DAG.getSetCC(dl, VT, Shift,
DAG.getSignedConstant(NewC, dl, OpVT), Cond);
}
}
}

Expand Down
24 changes: 8 additions & 16 deletions llvm/test/CodeGen/RISCV/and-negpow2-cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ define i1 @test5(i64 %x) {
;
; RV64-LABEL: test5:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 29
; RV64-NEXT: sraiw a0, a0, 29
; RV64-NEXT: seqz a0, a0
; RV64-NEXT: ret
%a = and i64 %x, u0xE0000000
Expand All @@ -91,7 +91,7 @@ define i1 @test6(i64 %x) {
;
; RV64-LABEL: test6:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 29
; RV64-NEXT: sraiw a0, a0, 29
; RV64-NEXT: snez a0, a0
; RV64-NEXT: ret
%a = and i64 %x, u0xE0000000
Expand All @@ -109,11 +109,8 @@ define i1 @test7(i64 %x) {
;
; RV64-LABEL: test7:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 29
; RV64-NEXT: li a1, 3
; RV64-NEXT: slli a0, a0, 29
; RV64-NEXT: slli a1, a1, 30
; RV64-NEXT: xor a0, a0, a1
; RV64-NEXT: sraiw a0, a0, 29
; RV64-NEXT: addi a0, a0, 2
; RV64-NEXT: seqz a0, a0
; RV64-NEXT: ret
%a = and i64 %x, u0xE0000000
Expand All @@ -131,11 +128,8 @@ define i1 @test8(i64 %x) {
;
; RV64-LABEL: test8:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 20
; RV64-NEXT: li a1, 1
; RV64-NEXT: slli a0, a0, 20
; RV64-NEXT: slli a1, a1, 31
; RV64-NEXT: xor a0, a0, a1
; RV64-NEXT: sraiw a0, a0, 20
; RV64-NEXT: xori a0, a0, -2048
; RV64-NEXT: snez a0, a0
; RV64-NEXT: ret
%a = and i64 %x, u0xFFF00000
Expand All @@ -153,10 +147,8 @@ define i1 @test9(i64 %x) {
;
; RV64-LABEL: test9:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 16
; RV64-NEXT: slli a0, a0, 16
; RV64-NEXT: lui a1, 32768
; RV64-NEXT: xor a0, a0, a1
; RV64-NEXT: sraiw a0, a0, 16
; RV64-NEXT: addi a0, a0, -2048
; RV64-NEXT: seqz a0, a0
; RV64-NEXT: ret
%a = and i64 %x, u0xFFFF0000
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/RISCV/bittest.ll
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,13 @@ define i64 @bittest_31_i64(i64 %a) nounwind {
;
; RV64ZBS-LABEL: bittest_31_i64:
; RV64ZBS: # %bb.0:
; RV64ZBS-NEXT: srliw a0, a0, 31
; RV64ZBS-NEXT: sraiw a0, a0, 31
; RV64ZBS-NEXT: seqz a0, a0
; RV64ZBS-NEXT: ret
;
; RV64XTHEADBS-LABEL: bittest_31_i64:
; RV64XTHEADBS: # %bb.0:
; RV64XTHEADBS-NEXT: srliw a0, a0, 31
; RV64XTHEADBS-NEXT: sraiw a0, a0, 31
; RV64XTHEADBS-NEXT: seqz a0, a0
; RV64XTHEADBS-NEXT: ret
%shr = lshr i64 %a, 31
Expand Down Expand Up @@ -3517,7 +3517,7 @@ define i32 @bittest_31_andeq0_i64(i64 %x) {
;
; RV64-LABEL: bittest_31_andeq0_i64:
; RV64: # %bb.0:
; RV64-NEXT: srliw a0, a0, 31
; RV64-NEXT: sraiw a0, a0, 31
; RV64-NEXT: seqz a0, a0
; RV64-NEXT: ret
%and = and i64 %x, 2147483648
Expand Down