Skip to content

Commit 8fd1484

Browse files
authored
[LegalizeTypes][RISCV] Use signed promotion for UADDSAT if that's what the target prefers. (#102842)
As noted in #102781 we can promote UADDSAT if we use sign extend instead of zero extend. The custom handler for RISC-V was using SIGN_EXTEND when the Zbb extension was enabled. With this change we no longer need the custom code.
1 parent 654d1f8 commit 8fd1484

File tree

3 files changed

+25
-30
lines changed

3 files changed

+25
-30
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,31 +1056,39 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
10561056
return matcher.getNode(ISD::USUBSAT, dl, Op1.getValueType(), Op1, Op2);
10571057
}
10581058

1059+
if (Opcode == ISD::UADDSAT) {
1060+
EVT OVT = Op1.getValueType();
1061+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
1062+
// We can promote if we use sign-extend. Do this if the target prefers.
1063+
if (TLI.isSExtCheaperThanZExt(OVT, NVT)) {
1064+
Op1 = SExtPromotedInteger(Op1);
1065+
Op2 = SExtPromotedInteger(Op2);
1066+
return matcher.getNode(ISD::UADDSAT, dl, NVT, Op1, Op2);
1067+
}
1068+
1069+
Op1 = ZExtPromotedInteger(Op1);
1070+
Op2 = ZExtPromotedInteger(Op2);
1071+
unsigned NewBits = NVT.getScalarSizeInBits();
1072+
APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
1073+
SDValue SatMax = DAG.getConstant(MaxVal, dl, NVT);
1074+
SDValue Add = matcher.getNode(ISD::ADD, dl, NVT, Op1, Op2);
1075+
return matcher.getNode(ISD::UMIN, dl, NVT, Add, SatMax);
1076+
}
1077+
10591078
bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
10601079

10611080
// FIXME: We need vp-aware PromotedInteger functions.
10621081
SDValue Op1Promoted, Op2Promoted;
10631082
if (IsShift) {
10641083
Op1Promoted = GetPromotedInteger(Op1);
10651084
Op2Promoted = ZExtPromotedInteger(Op2);
1066-
} else if (Opcode == ISD::UADDSAT) {
1067-
Op1Promoted = ZExtPromotedInteger(Op1);
1068-
Op2Promoted = ZExtPromotedInteger(Op2);
10691085
} else {
10701086
Op1Promoted = SExtPromotedInteger(Op1);
10711087
Op2Promoted = SExtPromotedInteger(Op2);
10721088
}
10731089
EVT PromotedType = Op1Promoted.getValueType();
10741090
unsigned NewBits = PromotedType.getScalarSizeInBits();
10751091

1076-
if (Opcode == ISD::UADDSAT) {
1077-
APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
1078-
SDValue SatMax = DAG.getConstant(MaxVal, dl, PromotedType);
1079-
SDValue Add =
1080-
matcher.getNode(ISD::ADD, dl, PromotedType, Op1Promoted, Op2Promoted);
1081-
return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
1082-
}
1083-
10841092
// Shift cannot use a min/max expansion, we can't detect overflow if all of
10851093
// the bits have been shifted out.
10861094
if (IsShift || matcher.isOperationLegal(Opcode, PromotedType)) {

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
268268
setOperationAction(ISD::LOAD, MVT::i32, Custom);
269269
setOperationAction({ISD::ADD, ISD::SUB, ISD::SHL, ISD::SRA, ISD::SRL},
270270
MVT::i32, Custom);
271-
setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT}, MVT::i32,
272-
Custom);
271+
setOperationAction({ISD::UADDO, ISD::USUBO}, MVT::i32, Custom);
273272
if (!Subtarget.hasStdExtZbb())
274-
setOperationAction({ISD::SADDSAT, ISD::SSUBSAT, ISD::USUBSAT}, MVT::i32,
275-
Custom);
273+
setOperationAction(
274+
{ISD::SADDSAT, ISD::SSUBSAT, ISD::UADDSAT, ISD::USUBSAT}, MVT::i32,
275+
Custom);
276276
setOperationAction(ISD::SADDO, MVT::i32, Custom);
277277
}
278278
if (!Subtarget.hasStdExtZmmul()) {
@@ -12173,20 +12173,7 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1217312173
case ISD::UADDSAT:
1217412174
case ISD::USUBSAT: {
1217512175
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
12176-
"Unexpected custom legalisation");
12177-
if (Subtarget.hasStdExtZbb()) {
12178-
// With Zbb we can sign extend and let LegalizeDAG use minu/maxu. Using
12179-
// sign extend allows overflow of the lower 32 bits to be detected on
12180-
// the promoted size.
12181-
SDValue LHS =
12182-
DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(0));
12183-
SDValue RHS =
12184-
DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(1));
12185-
SDValue Res = DAG.getNode(N->getOpcode(), DL, MVT::i64, LHS, RHS);
12186-
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
12187-
return;
12188-
}
12189-
12176+
!Subtarget.hasStdExtZbb() && "Unexpected custom legalisation");
1219012177
// Without Zbb, expand to UADDO/USUBO+select which will trigger our custom
1219112178
// promotion for UADDO/USUBO.
1219212179
Results.push_back(expandAddSubSat(N, DAG));

llvm/test/CodeGen/RISCV/uadd_sat_plus.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
4040
;
4141
; RV64IZbb-LABEL: func32:
4242
; RV64IZbb: # %bb.0:
43+
; RV64IZbb-NEXT: sext.w a0, a0
4344
; RV64IZbb-NEXT: mulw a1, a1, a2
4445
; RV64IZbb-NEXT: not a2, a1
45-
; RV64IZbb-NEXT: sext.w a0, a0
4646
; RV64IZbb-NEXT: minu a0, a0, a2
4747
; RV64IZbb-NEXT: add a0, a0, a1
4848
; RV64IZbb-NEXT: ret

0 commit comments

Comments
 (0)