Skip to content

Commit d6f61ea

Browse files
committed
[SelectionDAG][RISCV] Treat zext nneg as sext in PromoteIntOp_ZERO_EXTEND if the promoted input is sign extended.
If the zext has the nneg flag and we can prove the promoted input is sign extended, we can avoid generating an AND that we might not be able to remove. RISC-V emits a lot of sext_inreg operations during i32->i64 promotion that makes this likely. I've restricted this to the case where the promoted type is the same as the result type so we don't need to create an additional extend. I've also restricted it to cases where the target has stated a preference for sext like i32->i64 on RV64. This is largely to avoid wasting time in computeNumSignBits until we have a test case that benefits.
1 parent 3d04f9f commit d6f61ea

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,9 +2605,22 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STRICT_UINT_TO_FP(SDNode *N) {
26052605

26062606
SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
26072607
SDLoc dl(N);
2608-
SDValue Op = GetPromotedInteger(N->getOperand(0));
2609-
Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
2610-
return DAG.getZeroExtendInReg(Op, dl, N->getOperand(0).getValueType());
2608+
SDValue Src = N->getOperand(0);
2609+
SDValue Op = GetPromotedInteger(Src);
2610+
EVT VT = N->getValueType(0);
2611+
2612+
// If this zext has the nneg flag and the target prefers sext, see if the
2613+
// promoted input is already sign extended.
2614+
// TODO: Should we have some way to set nneg on ISD::AND instead?
2615+
if (N->getFlags().hasNonNeg() && Op.getValueType() == VT &&
2616+
TLI.isSExtCheaperThanZExt(Src.getValueType(), VT)) {
2617+
unsigned OpEffectiveBits = DAG.ComputeMaxSignificantBits(Op);
2618+
if (OpEffectiveBits <= Src.getScalarValueSizeInBits())
2619+
return Op;
2620+
}
2621+
2622+
Op = DAG.getNode(ISD::ANY_EXTEND, dl, VT, Op);
2623+
return DAG.getZeroExtendInReg(Op, dl, Src.getValueType());
26112624
}
26122625

26132626
SDValue DAGTypeLegalizer::PromoteIntOp_VP_ZERO_EXTEND(SDNode *N) {

llvm/test/CodeGen/RISCV/shifts.ll

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -832,24 +832,22 @@ define i128 @shl128_shamt32_arith(i128 %a, i32 signext %b) nounwind {
832832
;
833833
; RV64I-LABEL: shl128_shamt32_arith:
834834
; RV64I: # %bb.0:
835-
; RV64I-NEXT: addi a2, a2, 1
836-
; RV64I-NEXT: slli a4, a2, 32
837-
; RV64I-NEXT: srli a4, a4, 32
835+
; RV64I-NEXT: addiw a4, a2, 1
838836
; RV64I-NEXT: addi a3, a4, -64
837+
; RV64I-NEXT: sll a2, a0, a4
839838
; RV64I-NEXT: bltz a3, .LBB17_2
840839
; RV64I-NEXT: # %bb.1:
841-
; RV64I-NEXT: sll a1, a0, a4
840+
; RV64I-NEXT: mv a1, a2
842841
; RV64I-NEXT: j .LBB17_3
843842
; RV64I-NEXT: .LBB17_2:
844-
; RV64I-NEXT: sll a1, a1, a2
845-
; RV64I-NEXT: srli a5, a0, 1
843+
; RV64I-NEXT: sll a1, a1, a4
844+
; RV64I-NEXT: srli a0, a0, 1
846845
; RV64I-NEXT: not a4, a4
847-
; RV64I-NEXT: srl a4, a5, a4
848-
; RV64I-NEXT: or a1, a1, a4
846+
; RV64I-NEXT: srl a0, a0, a4
847+
; RV64I-NEXT: or a1, a1, a0
849848
; RV64I-NEXT: .LBB17_3:
850-
; RV64I-NEXT: sll a0, a0, a2
851-
; RV64I-NEXT: srai a3, a3, 63
852-
; RV64I-NEXT: and a0, a3, a0
849+
; RV64I-NEXT: srai a0, a3, 63
850+
; RV64I-NEXT: and a0, a0, a2
853851
; RV64I-NEXT: ret
854852
%c = add i32 %b, 1
855853
%zext = zext nneg i32 %c to i128

0 commit comments

Comments
 (0)