[llvm] fa0f01a - [RISCV][LegalizeTypes] Teach type legalizer that it can promote UMIN/UMAX using SExtPromotedInteger if that's better for the target.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 27 11:39:01 PST 2020


Author: Craig Topper
Date: 2020-11-27T11:37:25-08:00
New Revision: fa0f01a3c0e1bdc1a0b4e1188445335184eae03c

URL: https://github.com/llvm/llvm-project/commit/fa0f01a3c0e1bdc1a0b4e1188445335184eae03c
DIFF: https://github.com/llvm/llvm-project/commit/fa0f01a3c0e1bdc1a0b4e1188445335184eae03c.diff

LOG: [RISCV][LegalizeTypes] Teach type legalizer that it can promote UMIN/UMAX using SExtPromotedInteger if that's better for the target.

If Sext is cheaper than Zext for a target, we can use that to promote the operands of UMIN/UMAX. Using sext just makes numbers with the sign bit set even larger when treated as an unsigned number and it has no effect on number without the sign bit set. So the relative order doesn't change. This is similar to what we already do for promoting SETCC.

This is helpful on RISCV where i32 arguments are sign extended on RV64 and many instructions are able to produce results with 33 sign bits.

Differential Revision: https://reviews.llvm.org/D92128

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/test/CodeGen/RISCV/rv64Zbb.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 414e7692df2a..8468f51a922c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -82,7 +82,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::SMIN:
   case ISD::SMAX:        Res = PromoteIntRes_SExtIntBinOp(N); break;
   case ISD::UMIN:
-  case ISD::UMAX:        Res = PromoteIntRes_ZExtIntBinOp(N); break;
+  case ISD::UMAX:        Res = PromoteIntRes_UMINUMAX(N); break;
 
   case ISD::SHL:         Res = PromoteIntRes_SHL(N); break;
   case ISD::SIGN_EXTEND_INREG:
@@ -1101,6 +1101,15 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ZExtIntBinOp(SDNode *N) {
                      LHS.getValueType(), LHS, RHS);
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_UMINUMAX(SDNode *N) {
+  // It doesn't matter if we sign extend or zero extend in the inputs. So do
+  // whatever is best for the target.
+  SDValue LHS = SExtOrZExtPromotedInteger(N->getOperand(0));
+  SDValue RHS = SExtOrZExtPromotedInteger(N->getOperand(1));
+  return DAG.getNode(N->getOpcode(), SDLoc(N),
+                     LHS.getValueType(), LHS, RHS);
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
   // The input value must be properly sign extended.
   SDValue LHS = SExtPromotedInteger(N->getOperand(0));

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index fdc829b61b65..fed111f4d64e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -331,6 +331,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue PromoteIntRes_SimpleIntBinOp(SDNode *N);
   SDValue PromoteIntRes_ZExtIntBinOp(SDNode *N);
   SDValue PromoteIntRes_SExtIntBinOp(SDNode *N);
+  SDValue PromoteIntRes_UMINUMAX(SDNode *N);
   SDValue PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N);
   SDValue PromoteIntRes_SRA(SDNode *N);
   SDValue PromoteIntRes_SRL(SDNode *N);

diff  --git a/llvm/test/CodeGen/RISCV/rv64Zbb.ll b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
index 3c96af27c057..eb9698adba87 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
@@ -856,18 +856,12 @@ define signext i32 @minu_i32(i32 signext %a, i32 signext %b) nounwind {
 ;
 ; RV64IB-LABEL: minu_i32:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    zext.w a1, a1
-; RV64IB-NEXT:    zext.w a0, a0
 ; RV64IB-NEXT:    minu a0, a0, a1
-; RV64IB-NEXT:    sext.w a0, a0
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBB-LABEL: minu_i32:
 ; RV64IBB:       # %bb.0:
-; RV64IBB-NEXT:    zext.w a1, a1
-; RV64IBB-NEXT:    zext.w a0, a0
 ; RV64IBB-NEXT:    minu a0, a0, a1
-; RV64IBB-NEXT:    sext.w a0, a0
 ; RV64IBB-NEXT:    ret
   %cmp = icmp ult i32 %a, %b
   %cond = select i1 %cmp, i32 %a, i32 %b
@@ -908,18 +902,12 @@ define signext i32 @maxu_i32(i32 signext %a, i32 signext %b) nounwind {
 ;
 ; RV64IB-LABEL: maxu_i32:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    zext.w a1, a1
-; RV64IB-NEXT:    zext.w a0, a0
 ; RV64IB-NEXT:    maxu a0, a0, a1
-; RV64IB-NEXT:    sext.w a0, a0
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBB-LABEL: maxu_i32:
 ; RV64IBB:       # %bb.0:
-; RV64IBB-NEXT:    zext.w a1, a1
-; RV64IBB-NEXT:    zext.w a0, a0
 ; RV64IBB-NEXT:    maxu a0, a0, a1
-; RV64IBB-NEXT:    sext.w a0, a0
 ; RV64IBB-NEXT:    ret
   %cmp = icmp ugt i32 %a, %b
   %cond = select i1 %cmp, i32 %a, i32 %b


        


More information about the llvm-commits mailing list