-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[RISCV] Custom legalize i32 saddo/ssubo on RV64 to return a sign extended value for the data result. #172112
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
Merged
+50
−45
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…nded value for the data result. This is consistent with how we handle regular ADD/SUB and helps with computeNumSignBits optimizations. Fixes llvm#172089
Member
|
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesThis is consistent with how we handle regular ADD/SUB and helps with computeNumSignBits optimizations. Fixes #172089 Full diff: https://github.com/llvm/llvm-project/pull/172112.diff 5 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2c0a02ae396c7..e84179ac11e7f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -358,7 +358,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(
{ISD::SADDSAT, ISD::SSUBSAT, ISD::UADDSAT, ISD::USUBSAT}, MVT::i32,
Custom);
- setOperationAction(ISD::SADDO, MVT::i32, Custom);
+ setOperationAction({ISD::SADDO, ISD::SSUBO}, MVT::i32, Custom);
}
if (!Subtarget.hasStdExtZmmul()) {
setOperationAction({ISD::MUL, ISD::MULHS, ISD::MULHU}, XLenVT, Expand);
@@ -15060,35 +15060,42 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc));
break;
}
- case ISD::SADDO: {
+ case ISD::SADDO:
+ case ISD::SSUBO: {
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
"Unexpected custom legalisation");
- // If the RHS is a constant, we can simplify ConditionRHS below. Otherwise
- // use the default legalization.
- if (!isa<ConstantSDNode>(N->getOperand(1)))
- return;
-
+ // This is similar to the default legalization, but we return the
+ // sext_inreg instead of the add/sub.
+ bool IsAdd = N->getOpcode() == ISD::SADDO;
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(ISD::ADD, DL, MVT::i64, LHS, RHS);
- Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Res,
- DAG.getValueType(MVT::i32));
+ SDValue Op =
+ DAG.getNode(IsAdd ? ISD::ADD : ISD::SUB, DL, MVT::i64, LHS, RHS);
+ SDValue Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Op,
+ DAG.getValueType(MVT::i32));
- SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
+ SDValue Overflow;
- // For an addition, the result should be less than one of the operands (LHS)
- // if and only if the other operand (RHS) is negative, otherwise there will
- // be overflow.
- // For a subtraction, the result should be less than one of the operands
- // (LHS) if and only if the other operand (RHS) is (non-zero) positive,
- // otherwise there will be overflow.
- EVT OType = N->getValueType(1);
- SDValue ResultLowerThanLHS = DAG.getSetCC(DL, OType, Res, LHS, ISD::SETLT);
- SDValue ConditionRHS = DAG.getSetCC(DL, OType, RHS, Zero, ISD::SETLT);
+ // If the RHS is a constant, we can simplify ConditionRHS below. Otherwise
+ // use the default legalization.
+ if (IsAdd && isa<ConstantSDNode>(N->getOperand(1))) {
+ SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
+
+ // For an addition, the result should be less than one of the operands
+ // (LHS) if and only if the other operand (RHS) is negative, otherwise
+ // there will be overflow.
+ EVT OType = N->getValueType(1);
+ SDValue ResultLowerThanLHS =
+ DAG.getSetCC(DL, OType, Res, LHS, ISD::SETLT);
+ SDValue ConditionRHS = DAG.getSetCC(DL, OType, RHS, Zero, ISD::SETLT);
+
+ Overflow =
+ DAG.getNode(ISD::XOR, DL, OType, ConditionRHS, ResultLowerThanLHS);
+ } else {
+ Overflow = DAG.getSetCC(DL, N->getValueType(1), Res, Op, ISD::SETNE);
+ }
- SDValue Overflow =
- DAG.getNode(ISD::XOR, DL, OType, ConditionRHS, ResultLowerThanLHS);
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
Results.push_back(Overflow);
return;
diff --git a/llvm/test/CodeGen/RISCV/sadd_sat.ll b/llvm/test/CodeGen/RISCV/sadd_sat.ll
index 27c7518c4f6c4..b7173ce5c0c07 100644
--- a/llvm/test/CodeGen/RISCV/sadd_sat.ll
+++ b/llvm/test/CodeGen/RISCV/sadd_sat.ll
@@ -21,16 +21,15 @@ define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
;
; RV64I-LABEL: func:
; RV64I: # %bb.0:
-; RV64I-NEXT: add a2, a0, a1
+; RV64I-NEXT: mv a2, a0
; RV64I-NEXT: addw a0, a0, a1
-; RV64I-NEXT: beq a0, a2, .LBB0_2
+; RV64I-NEXT: add a1, a2, a1
+; RV64I-NEXT: beq a0, a1, .LBB0_2
; RV64I-NEXT: # %bb.1:
-; RV64I-NEXT: srli a0, a0, 31
-; RV64I-NEXT: li a1, 1
-; RV64I-NEXT: slli a1, a1, 31
-; RV64I-NEXT: xor a2, a0, a1
+; RV64I-NEXT: sraiw a0, a1, 31
+; RV64I-NEXT: lui a1, 524288
+; RV64I-NEXT: xor a0, a0, a1
; RV64I-NEXT: .LBB0_2:
-; RV64I-NEXT: sext.w a0, a2
; RV64I-NEXT: ret
;
; RV64IZbb-LABEL: func:
diff --git a/llvm/test/CodeGen/RISCV/sadd_sat_plus.ll b/llvm/test/CodeGen/RISCV/sadd_sat_plus.ll
index 108a214535c3e..5c9588173289b 100644
--- a/llvm/test/CodeGen/RISCV/sadd_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/sadd_sat_plus.ll
@@ -22,13 +22,13 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
;
; RV64I-LABEL: func32:
; RV64I: # %bb.0:
-; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: mulw a1, a1, a2
-; RV64I-NEXT: addw a2, a0, a1
-; RV64I-NEXT: add a0, a0, a1
-; RV64I-NEXT: beq a2, a0, .LBB0_2
+; RV64I-NEXT: sext.w a2, a0
+; RV64I-NEXT: addw a0, a2, a1
+; RV64I-NEXT: add a1, a2, a1
+; RV64I-NEXT: beq a0, a1, .LBB0_2
; RV64I-NEXT: # %bb.1:
-; RV64I-NEXT: sraiw a0, a0, 31
+; RV64I-NEXT: sraiw a0, a1, 31
; RV64I-NEXT: lui a1, 524288
; RV64I-NEXT: xor a0, a0, a1
; RV64I-NEXT: .LBB0_2:
diff --git a/llvm/test/CodeGen/RISCV/ssub_sat.ll b/llvm/test/CodeGen/RISCV/ssub_sat.ll
index 0ee97d6660451..62556e5a69c66 100644
--- a/llvm/test/CodeGen/RISCV/ssub_sat.ll
+++ b/llvm/test/CodeGen/RISCV/ssub_sat.ll
@@ -21,16 +21,15 @@ define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
;
; RV64I-LABEL: func:
; RV64I: # %bb.0:
-; RV64I-NEXT: sub a2, a0, a1
+; RV64I-NEXT: mv a2, a0
; RV64I-NEXT: subw a0, a0, a1
+; RV64I-NEXT: sub a2, a2, a1
; RV64I-NEXT: beq a0, a2, .LBB0_2
; RV64I-NEXT: # %bb.1:
-; RV64I-NEXT: srli a0, a0, 31
-; RV64I-NEXT: li a1, 1
-; RV64I-NEXT: slli a1, a1, 31
-; RV64I-NEXT: xor a2, a0, a1
+; RV64I-NEXT: sraiw a0, a2, 31
+; RV64I-NEXT: lui a1, 524288
+; RV64I-NEXT: xor a0, a0, a1
; RV64I-NEXT: .LBB0_2:
-; RV64I-NEXT: sext.w a0, a2
; RV64I-NEXT: ret
;
; RV64IZbb-LABEL: func:
diff --git a/llvm/test/CodeGen/RISCV/ssub_sat_plus.ll b/llvm/test/CodeGen/RISCV/ssub_sat_plus.ll
index f74cbd442ab83..00e785552f5fc 100644
--- a/llvm/test/CodeGen/RISCV/ssub_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/ssub_sat_plus.ll
@@ -22,13 +22,13 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
;
; RV64I-LABEL: func32:
; RV64I: # %bb.0:
-; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: mulw a1, a1, a2
-; RV64I-NEXT: subw a2, a0, a1
-; RV64I-NEXT: sub a0, a0, a1
-; RV64I-NEXT: beq a2, a0, .LBB0_2
+; RV64I-NEXT: sext.w a2, a0
+; RV64I-NEXT: subw a0, a2, a1
+; RV64I-NEXT: sub a1, a2, a1
+; RV64I-NEXT: beq a0, a1, .LBB0_2
; RV64I-NEXT: # %bb.1:
-; RV64I-NEXT: sraiw a0, a0, 31
+; RV64I-NEXT: sraiw a0, a1, 31
; RV64I-NEXT: lui a1, 524288
; RV64I-NEXT: xor a0, a0, a1
; RV64I-NEXT: .LBB0_2:
|
wangpc-pp
approved these changes
Dec 15, 2025
Contributor
wangpc-pp
left a comment
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is consistent with how we handle regular ADD/SUB and helps with computeNumSignBits optimizations.
Fixes #172089