-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[LegalizeTypes][RISCV] Use signed promotion for UADDSAT if that's what the target prefers. #102842
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
Conversation
…t the target prefers.
@llvm/pr-subscribers-llvm-selectiondag Author: Craig Topper (topperc) ChangesAs 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. Full diff: https://github.com/llvm/llvm-project/pull/102842.diff 3 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 3635bc7a965804..174b3820693f5f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1056,6 +1056,25 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
return matcher.getNode(ISD::USUBSAT, dl, Op1.getValueType(), Op1, Op2);
}
+ if (Opcode == ISD::UADDSAT) {
+ EVT OVT = Op1.getValueType();
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
+ // We can promote if we use sign-extend. Do this if the target prefers.
+ if (TLI.isSExtCheaperThanZExt(OVT, NVT)) {
+ Op1 = SExtPromotedInteger(Op1);
+ Op2 = SExtPromotedInteger(Op2);
+ return matcher.getNode(ISD::UADDSAT, dl, NVT, Op1, Op2);
+ }
+
+ Op1 = ZExtPromotedInteger(Op1);
+ Op2 = ZExtPromotedInteger(Op2);
+ unsigned NewBits = NVT.getScalarSizeInBits();
+ APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
+ SDValue SatMax = DAG.getConstant(MaxVal, dl, NVT);
+ SDValue Add = matcher.getNode(ISD::ADD, dl, NVT, Op1, Op2);
+ return matcher.getNode(ISD::UMIN, dl, NVT, Add, SatMax);
+ }
+
bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
// FIXME: We need vp-aware PromotedInteger functions.
@@ -1063,9 +1082,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
if (IsShift) {
Op1Promoted = GetPromotedInteger(Op1);
Op2Promoted = ZExtPromotedInteger(Op2);
- } else if (Opcode == ISD::UADDSAT) {
- Op1Promoted = ZExtPromotedInteger(Op1);
- Op2Promoted = ZExtPromotedInteger(Op2);
} else {
Op1Promoted = SExtPromotedInteger(Op1);
Op2Promoted = SExtPromotedInteger(Op2);
@@ -1073,14 +1089,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
EVT PromotedType = Op1Promoted.getValueType();
unsigned NewBits = PromotedType.getScalarSizeInBits();
- if (Opcode == ISD::UADDSAT) {
- APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
- SDValue SatMax = DAG.getConstant(MaxVal, dl, PromotedType);
- SDValue Add =
- matcher.getNode(ISD::ADD, dl, PromotedType, Op1Promoted, Op2Promoted);
- return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
- }
-
// Shift cannot use a min/max expansion, we can't detect overflow if all of
// the bits have been shifted out.
if (IsShift || matcher.isOperationLegal(Opcode, PromotedType)) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 872c288f5ad8cd..732d4fed036d8a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -268,11 +268,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::LOAD, MVT::i32, Custom);
setOperationAction({ISD::ADD, ISD::SUB, ISD::SHL, ISD::SRA, ISD::SRL},
MVT::i32, Custom);
- setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT}, MVT::i32,
- Custom);
+ setOperationAction({ISD::UADDO, ISD::USUBO}, MVT::i32, Custom);
if (!Subtarget.hasStdExtZbb())
- setOperationAction({ISD::SADDSAT, ISD::SSUBSAT, ISD::USUBSAT}, MVT::i32,
- Custom);
+ setOperationAction(
+ {ISD::SADDSAT, ISD::SSUBSAT, ISD::UADDSAT, ISD::USUBSAT}, MVT::i32,
+ Custom);
setOperationAction(ISD::SADDO, MVT::i32, Custom);
}
if (!Subtarget.hasStdExtZmmul()) {
@@ -12173,20 +12173,7 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
case ISD::UADDSAT:
case ISD::USUBSAT: {
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
- "Unexpected custom legalisation");
- if (Subtarget.hasStdExtZbb()) {
- // With Zbb we can sign extend and let LegalizeDAG use minu/maxu. Using
- // sign extend allows overflow of the lower 32 bits to be detected on
- // the promoted size.
- SDValue LHS =
- DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(0));
- SDValue RHS =
- DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(1));
- SDValue Res = DAG.getNode(N->getOpcode(), DL, MVT::i64, LHS, RHS);
- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
- return;
- }
-
+ !Subtarget.hasStdExtZbb() && "Unexpected custom legalisation");
// Without Zbb, expand to UADDO/USUBO+select which will trigger our custom
// promotion for UADDO/USUBO.
Results.push_back(expandAddSubSat(N, DAG));
diff --git a/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll b/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
index 219f0daf270bc1..23875a7ec56211 100644
--- a/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
@@ -40,9 +40,9 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
;
; RV64IZbb-LABEL: func32:
; RV64IZbb: # %bb.0:
+; RV64IZbb-NEXT: sext.w a0, a0
; RV64IZbb-NEXT: mulw a1, a1, a2
; RV64IZbb-NEXT: not a2, a1
-; RV64IZbb-NEXT: sext.w a0, a0
; RV64IZbb-NEXT: minu a0, a0, a2
; RV64IZbb-NEXT: add a0, a0, a1
; RV64IZbb-NEXT: ret
|
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesAs 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. Full diff: https://github.com/llvm/llvm-project/pull/102842.diff 3 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 3635bc7a965804..174b3820693f5f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1056,6 +1056,25 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
return matcher.getNode(ISD::USUBSAT, dl, Op1.getValueType(), Op1, Op2);
}
+ if (Opcode == ISD::UADDSAT) {
+ EVT OVT = Op1.getValueType();
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
+ // We can promote if we use sign-extend. Do this if the target prefers.
+ if (TLI.isSExtCheaperThanZExt(OVT, NVT)) {
+ Op1 = SExtPromotedInteger(Op1);
+ Op2 = SExtPromotedInteger(Op2);
+ return matcher.getNode(ISD::UADDSAT, dl, NVT, Op1, Op2);
+ }
+
+ Op1 = ZExtPromotedInteger(Op1);
+ Op2 = ZExtPromotedInteger(Op2);
+ unsigned NewBits = NVT.getScalarSizeInBits();
+ APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
+ SDValue SatMax = DAG.getConstant(MaxVal, dl, NVT);
+ SDValue Add = matcher.getNode(ISD::ADD, dl, NVT, Op1, Op2);
+ return matcher.getNode(ISD::UMIN, dl, NVT, Add, SatMax);
+ }
+
bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
// FIXME: We need vp-aware PromotedInteger functions.
@@ -1063,9 +1082,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
if (IsShift) {
Op1Promoted = GetPromotedInteger(Op1);
Op2Promoted = ZExtPromotedInteger(Op2);
- } else if (Opcode == ISD::UADDSAT) {
- Op1Promoted = ZExtPromotedInteger(Op1);
- Op2Promoted = ZExtPromotedInteger(Op2);
} else {
Op1Promoted = SExtPromotedInteger(Op1);
Op2Promoted = SExtPromotedInteger(Op2);
@@ -1073,14 +1089,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
EVT PromotedType = Op1Promoted.getValueType();
unsigned NewBits = PromotedType.getScalarSizeInBits();
- if (Opcode == ISD::UADDSAT) {
- APInt MaxVal = APInt::getLowBitsSet(NewBits, OldBits);
- SDValue SatMax = DAG.getConstant(MaxVal, dl, PromotedType);
- SDValue Add =
- matcher.getNode(ISD::ADD, dl, PromotedType, Op1Promoted, Op2Promoted);
- return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
- }
-
// Shift cannot use a min/max expansion, we can't detect overflow if all of
// the bits have been shifted out.
if (IsShift || matcher.isOperationLegal(Opcode, PromotedType)) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 872c288f5ad8cd..732d4fed036d8a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -268,11 +268,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::LOAD, MVT::i32, Custom);
setOperationAction({ISD::ADD, ISD::SUB, ISD::SHL, ISD::SRA, ISD::SRL},
MVT::i32, Custom);
- setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT}, MVT::i32,
- Custom);
+ setOperationAction({ISD::UADDO, ISD::USUBO}, MVT::i32, Custom);
if (!Subtarget.hasStdExtZbb())
- setOperationAction({ISD::SADDSAT, ISD::SSUBSAT, ISD::USUBSAT}, MVT::i32,
- Custom);
+ setOperationAction(
+ {ISD::SADDSAT, ISD::SSUBSAT, ISD::UADDSAT, ISD::USUBSAT}, MVT::i32,
+ Custom);
setOperationAction(ISD::SADDO, MVT::i32, Custom);
}
if (!Subtarget.hasStdExtZmmul()) {
@@ -12173,20 +12173,7 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
case ISD::UADDSAT:
case ISD::USUBSAT: {
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
- "Unexpected custom legalisation");
- if (Subtarget.hasStdExtZbb()) {
- // With Zbb we can sign extend and let LegalizeDAG use minu/maxu. Using
- // sign extend allows overflow of the lower 32 bits to be detected on
- // the promoted size.
- SDValue LHS =
- DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(0));
- SDValue RHS =
- DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, N->getOperand(1));
- SDValue Res = DAG.getNode(N->getOpcode(), DL, MVT::i64, LHS, RHS);
- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
- return;
- }
-
+ !Subtarget.hasStdExtZbb() && "Unexpected custom legalisation");
// Without Zbb, expand to UADDO/USUBO+select which will trigger our custom
// promotion for UADDO/USUBO.
Results.push_back(expandAddSubSat(N, DAG));
diff --git a/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll b/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
index 219f0daf270bc1..23875a7ec56211 100644
--- a/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll
@@ -40,9 +40,9 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
;
; RV64IZbb-LABEL: func32:
; RV64IZbb: # %bb.0:
+; RV64IZbb-NEXT: sext.w a0, a0
; RV64IZbb-NEXT: mulw a1, a1, a2
; RV64IZbb-NEXT: not a2, a1
-; RV64IZbb-NEXT: sext.w a0, a0
; RV64IZbb-NEXT: minu a0, a0, a2
; RV64IZbb-NEXT: add a0, a0, a1
; RV64IZbb-NEXT: ret
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/3847 Here is the relevant piece of the build log for the reference:
|
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.