Skip to content

[LegalizeTypes][RISCV] Use SExtOrZExtPromotedOperands to promote operands for USUBSAT. #102781

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
merged 1 commit into from
Aug 11, 2024

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Aug 11, 2024

It doesn't matter which extend we use to promote the operands. Use whatever is the most efficient.

The custom handler for RISC-V was using SIGN_EXTEND when the Zbb extension is enabled so we no longer need that.

…ands for USUBSAT.

I doesn't matter which extend we use to promote the operands. Use
whatever is the most efficient.

The custom handler for RISC-V was using SIGN_EXTEND when the Zbb
extension is enabled so we no longer need that.
@topperc topperc requested review from nikic and RKSimon August 11, 2024 01:37
@llvmbot llvmbot added backend:RISC-V llvm:SelectionDAG SelectionDAGISel as well labels Aug 11, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 11, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

It doesn't matter which extend we use to promote the operands. Use whatever is the most efficient.

The custom handler for RISC-V was using SIGN_EXTEND when the Zbb extension is enabled so we no longer need that.


Full diff: https://github.com/llvm/llvm-project/pull/102781.diff

3 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (+10-7)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+4-3)
  • (modified) llvm/test/CodeGen/RISCV/usub_sat_plus.ll (+1-1)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 79ff33aa705ef3..3635bc7a965804 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1045,9 +1045,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
   SDValue Op1 = N->getOperand(0);
   SDValue Op2 = N->getOperand(1);
   MatchContextClass matcher(DAG, TLI, N);
-  unsigned OldBits = Op1.getScalarValueSizeInBits();
 
   unsigned Opcode = matcher.getRootBaseOpcode();
+  unsigned OldBits = Op1.getScalarValueSizeInBits();
+
+  // USUBSAT can always be promoted as long as we have zero/sign-extended the
+  // args.
+  if (Opcode == ISD::USUBSAT) {
+    SExtOrZExtPromotedOperands(Op1, Op2);
+    return matcher.getNode(ISD::USUBSAT, dl, Op1.getValueType(), Op1, Op2);
+  }
+
   bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
 
   // FIXME: We need vp-aware PromotedInteger functions.
@@ -1055,7 +1063,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
   if (IsShift) {
     Op1Promoted = GetPromotedInteger(Op1);
     Op2Promoted = ZExtPromotedInteger(Op2);
-  } else if (Opcode == ISD::UADDSAT || Opcode == ISD::USUBSAT) {
+  } else if (Opcode == ISD::UADDSAT) {
     Op1Promoted = ZExtPromotedInteger(Op1);
     Op2Promoted = ZExtPromotedInteger(Op2);
   } else {
@@ -1073,11 +1081,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
     return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
   }
 
-  // USUBSAT can always be promoted as long as we have zero-extended the args.
-  if (Opcode == ISD::USUBSAT)
-    return matcher.getNode(ISD::USUBSAT, dl, PromotedType, Op1Promoted,
-                           Op2Promoted);
-
   // 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 d6d96dd4edf8ad..872c288f5ad8cd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -268,10 +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, ISD::USUBSAT},
-                       MVT::i32, Custom);
+    setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT}, MVT::i32,
+                       Custom);
     if (!Subtarget.hasStdExtZbb())
-      setOperationAction({ISD::SADDSAT, ISD::SSUBSAT}, MVT::i32, Custom);
+      setOperationAction({ISD::SADDSAT, ISD::SSUBSAT, ISD::USUBSAT}, MVT::i32,
+                         Custom);
     setOperationAction(ISD::SADDO, MVT::i32, Custom);
   }
   if (!Subtarget.hasStdExtZmmul()) {
diff --git a/llvm/test/CodeGen/RISCV/usub_sat_plus.ll b/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
index 393466d89e8ca9..c76a53468f7689 100644
--- a/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
@@ -39,8 +39,8 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
 ;
 ; RV64IZbb-LABEL: func32:
 ; RV64IZbb:       # %bb.0:
-; RV64IZbb-NEXT:    mulw a1, a1, a2
 ; RV64IZbb-NEXT:    sext.w a0, a0
+; RV64IZbb-NEXT:    mulw a1, a1, a2
 ; RV64IZbb-NEXT:    maxu a0, a0, a1
 ; RV64IZbb-NEXT:    sub a0, a0, a1
 ; RV64IZbb-NEXT:    ret

@llvmbot
Copy link
Member

llvmbot commented Aug 11, 2024

@llvm/pr-subscribers-llvm-selectiondag

Author: Craig Topper (topperc)

Changes

It doesn't matter which extend we use to promote the operands. Use whatever is the most efficient.

The custom handler for RISC-V was using SIGN_EXTEND when the Zbb extension is enabled so we no longer need that.


Full diff: https://github.com/llvm/llvm-project/pull/102781.diff

3 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (+10-7)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+4-3)
  • (modified) llvm/test/CodeGen/RISCV/usub_sat_plus.ll (+1-1)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 79ff33aa705ef3..3635bc7a965804 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1045,9 +1045,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
   SDValue Op1 = N->getOperand(0);
   SDValue Op2 = N->getOperand(1);
   MatchContextClass matcher(DAG, TLI, N);
-  unsigned OldBits = Op1.getScalarValueSizeInBits();
 
   unsigned Opcode = matcher.getRootBaseOpcode();
+  unsigned OldBits = Op1.getScalarValueSizeInBits();
+
+  // USUBSAT can always be promoted as long as we have zero/sign-extended the
+  // args.
+  if (Opcode == ISD::USUBSAT) {
+    SExtOrZExtPromotedOperands(Op1, Op2);
+    return matcher.getNode(ISD::USUBSAT, dl, Op1.getValueType(), Op1, Op2);
+  }
+
   bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
 
   // FIXME: We need vp-aware PromotedInteger functions.
@@ -1055,7 +1063,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
   if (IsShift) {
     Op1Promoted = GetPromotedInteger(Op1);
     Op2Promoted = ZExtPromotedInteger(Op2);
-  } else if (Opcode == ISD::UADDSAT || Opcode == ISD::USUBSAT) {
+  } else if (Opcode == ISD::UADDSAT) {
     Op1Promoted = ZExtPromotedInteger(Op1);
     Op2Promoted = ZExtPromotedInteger(Op2);
   } else {
@@ -1073,11 +1081,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
     return matcher.getNode(ISD::UMIN, dl, PromotedType, Add, SatMax);
   }
 
-  // USUBSAT can always be promoted as long as we have zero-extended the args.
-  if (Opcode == ISD::USUBSAT)
-    return matcher.getNode(ISD::USUBSAT, dl, PromotedType, Op1Promoted,
-                           Op2Promoted);
-
   // 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 d6d96dd4edf8ad..872c288f5ad8cd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -268,10 +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, ISD::USUBSAT},
-                       MVT::i32, Custom);
+    setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT}, MVT::i32,
+                       Custom);
     if (!Subtarget.hasStdExtZbb())
-      setOperationAction({ISD::SADDSAT, ISD::SSUBSAT}, MVT::i32, Custom);
+      setOperationAction({ISD::SADDSAT, ISD::SSUBSAT, ISD::USUBSAT}, MVT::i32,
+                         Custom);
     setOperationAction(ISD::SADDO, MVT::i32, Custom);
   }
   if (!Subtarget.hasStdExtZmmul()) {
diff --git a/llvm/test/CodeGen/RISCV/usub_sat_plus.ll b/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
index 393466d89e8ca9..c76a53468f7689 100644
--- a/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
+++ b/llvm/test/CodeGen/RISCV/usub_sat_plus.ll
@@ -39,8 +39,8 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
 ;
 ; RV64IZbb-LABEL: func32:
 ; RV64IZbb:       # %bb.0:
-; RV64IZbb-NEXT:    mulw a1, a1, a2
 ; RV64IZbb-NEXT:    sext.w a0, a0
+; RV64IZbb-NEXT:    mulw a1, a1, a2
 ; RV64IZbb-NEXT:    maxu a0, a0, a1
 ; RV64IZbb-NEXT:    sub a0, a0, a1
 ; RV64IZbb-NEXT:    ret

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, proof: https://alive2.llvm.org/ce/z/hJRwjh

Also works for uaddsat if we used straightforward promotion, but not for the umax pattern we currently generate.

@topperc topperc merged commit 257c479 into llvm:main Aug 11, 2024
9 of 11 checks passed
@topperc topperc deleted the pr/usubsat-promotion branch August 11, 2024 17:22
topperc added a commit that referenced this pull request Aug 12, 2024
…t 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants