-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[RISCV] Fold (X & (7 << 29)) == 0 -> (srliw X, 29) == 0 for RV64. #156769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16726,10 +16726,6 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC, | |
| DAG.getConstant(0, DL, XLenVT), CC); | ||
| } | ||
|
|
||
| // Replace (seteq (i64 (and X, 0xffffffff)), C1) with | ||
| // (seteq (i64 (sext_inreg (X, i32)), C1')) where C1' is C1 sign extended from | ||
| // bit 31. Same for setne. C1' may be cheaper to materialize and the sext_inreg | ||
| // can become a sext.w instead of a shift pair. | ||
| static SDValue performSETCCCombine(SDNode *N, | ||
| TargetLowering::DAGCombinerInfo &DCI, | ||
| const RISCVSubtarget &Subtarget) { | ||
|
|
@@ -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 && | ||
|
||
| 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); | ||
| } | ||
| } | ||
|
|
||
| // Replace (seteq (i64 (and X, 0xffffffff)), C1) with | ||
| // (seteq (i64 (sext_inreg (X, i32)), C1')) where C1' is C1 sign extended from | ||
| // bit 31. Same for setne. C1' may be cheaper to materialize and the | ||
| // sext_inreg can become a sext.w instead of a shift pair. | ||
| if (OpVT != MVT::i64 || !Subtarget.is64Bit()) | ||
| return SDValue(); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,3 +64,37 @@ define i1 @test4(i64 %x) { | |
| %b = icmp eq i64 %a, 0 | ||
| ret i1 %b | ||
| } | ||
|
|
||
| define i1 @test5(i64 %x) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you precommit the tests so we can see prior codegen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
They are in separate commits in the PR. |
||
| ; RV32-LABEL: test5: | ||
| ; RV32: # %bb.0: | ||
| ; RV32-NEXT: srli a0, a0, 29 | ||
| ; RV32-NEXT: seqz a0, a0 | ||
| ; RV32-NEXT: ret | ||
| ; | ||
| ; RV64-LABEL: test5: | ||
| ; RV64: # %bb.0: | ||
| ; RV64-NEXT: srliw a0, a0, 29 | ||
| ; RV64-NEXT: seqz a0, a0 | ||
| ; RV64-NEXT: ret | ||
| %a = and i64 %x, u0xE0000000 | ||
| %b = icmp eq i64 %a, 0 | ||
| ret i1 %b | ||
| } | ||
|
|
||
| define i1 @test6(i64 %x) { | ||
| ; RV32-LABEL: test6: | ||
| ; RV32: # %bb.0: | ||
| ; RV32-NEXT: srli a0, a0, 29 | ||
| ; RV32-NEXT: snez a0, a0 | ||
| ; RV32-NEXT: ret | ||
| ; | ||
| ; RV64-LABEL: test6: | ||
| ; RV64: # %bb.0: | ||
| ; RV64-NEXT: srliw a0, a0, 29 | ||
| ; RV64-NEXT: snez a0, a0 | ||
| ; RV64-NEXT: ret | ||
| %a = and i64 %x, u0xE0000000 | ||
| %b = icmp ne i64 %a, 0 | ||
| ret i1 %b | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.