[RISCV][LegalizeTypes] Teach type legalizer that it can promote UMIN/UMAX using SExtP...
authorCraig Topper <craig.topper@sifive.com>
Fri, 27 Nov 2020 19:20:24 +0000 (11:20 -0800)
committerCraig Topper <craig.topper@sifive.com>
Fri, 27 Nov 2020 19:37:25 +0000 (11:37 -0800)
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

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

index 414e769..8468f51 100644 (file)
@@ -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));
index fdc829b..fed111f 100644 (file)
@@ -331,6 +331,7 @@ private:
   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);
index 3c96af2..eb9698a 100644 (file)
@@ -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