[llvm] 50302fe - [SelectionDAG][RISCV] Use isSExtCheaperThanZExt to control whether sext or zext is used for constant folding any_extend.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 19 09:25:36 PDT 2021


Author: Craig Topper
Date: 2021-07-19T09:25:28-07:00
New Revision: 50302feb1d2cce4a9fee38621cc7596b3c66ff02

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

LOG: [SelectionDAG][RISCV] Use isSExtCheaperThanZExt to control whether sext or zext is used for constant folding any_extend.

RISCV would prefer a sign extended constant since that works better
with our constant materialization. We have an existing TLI hook we
use to control sign extension of setcc operands in type legalization.
That hook happens to do the right check we need here, but might be
straying from its original purpose. With only RISCV defining this
hook in tree, I wasn't sure if it was worth adding another hook
with identical behavior.

This is an alternative to D105785 where I tried to handle this in
the RISCV backend by not creating ANY_EXTENDs in some places.

Reviewed By: frasercrmck

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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/alu32.ll
    llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll
    llvm/test/CodeGen/RISCV/xaluo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e058c40ce6ff6..ba45ac92d3a15 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4605,10 +4605,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
       if (C->isOpaque())
         break;
       LLVM_FALLTHROUGH;
-    case ISD::ANY_EXTEND:
     case ISD::ZERO_EXTEND:
       return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT,
                          C->isTargetOpcode(), C->isOpaque());
+    case ISD::ANY_EXTEND:
+      // Some targets like RISCV prefer to sign extend some types.
+      if (TLI->isSExtCheaperThanZExt(Operand.getValueType(), VT))
+        return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), DL, VT,
+                           C->isTargetOpcode(), C->isOpaque());
+      return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT,
+                         C->isTargetOpcode(), C->isOpaque());
     case ISD::UINT_TO_FP:
     case ISD::SINT_TO_FP: {
       APFloat apf(EVTToAPFloatSemantics(VT),

diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index e7ea2e16dcfe3..3fed12aa697bb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4732,12 +4732,11 @@ static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
 // SLLW/DIVUW/.../*W later one because the fact the operation was originally of
 // type i8/i16/i32 is lost.
 static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG,
-                                   unsigned ExtOpc0 = ISD::ANY_EXTEND,
-                                   unsigned ExtOpc1 = ISD::ANY_EXTEND) {
+                                   unsigned ExtOpc = ISD::ANY_EXTEND) {
   SDLoc DL(N);
   RISCVISD::NodeType WOpcode = getRISCVWOpcode(N->getOpcode());
-  SDValue NewOp0 = DAG.getNode(ExtOpc0, DL, MVT::i64, N->getOperand(0));
-  SDValue NewOp1 = DAG.getNode(ExtOpc1, DL, MVT::i64, N->getOperand(1));
+  SDValue NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
+  SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1));
   SDValue NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
   // ReplaceNodeResults requires we maintain the same type for the return value.
   return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes);
@@ -4902,17 +4901,12 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
     // If the input is i32, use ANY_EXTEND since the W instructions don't read
     // the upper 32 bits. For other types we need to sign or zero extend
     // based on the opcode.
-    unsigned ExtOpc0 = ISD::ANY_EXTEND, ExtOpc1 = ISD::ANY_EXTEND;
-    if (VT != MVT::i32) {
-      ExtOpc0 = N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND
-                                            : ISD::ZERO_EXTEND;
-      ExtOpc1 = ExtOpc0;
-    } else if (N->getOperand(0).getOpcode() == ISD::Constant) {
-      // Sign extend i32 constants to improve materialization.
-      ExtOpc0 = ISD::SIGN_EXTEND;
-    }
+    unsigned ExtOpc = ISD::ANY_EXTEND;
+    if (VT != MVT::i32)
+      ExtOpc = N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND
+                                           : ISD::ZERO_EXTEND;
 
-    Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc0, ExtOpc1));
+    Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc));
     break;
   }
   case ISD::UADDO:

diff  --git a/llvm/test/CodeGen/RISCV/alu32.ll b/llvm/test/CodeGen/RISCV/alu32.ll
index 0779435f2bb39..b7cba24a43cd5 100644
--- a/llvm/test/CodeGen/RISCV/alu32.ll
+++ b/llvm/test/CodeGen/RISCV/alu32.ll
@@ -198,9 +198,7 @@ define i32 @sub_negative_constant_lhs(i32 %a) nounwind {
 ;
 ; RV64I-LABEL: sub_negative_constant_lhs:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addi a1, zero, 1
-; RV64I-NEXT:    slli a1, a1, 32
-; RV64I-NEXT:    addi a1, a1, -2
+; RV64I-NEXT:    addi a1, zero, -2
 ; RV64I-NEXT:    subw a0, a1, a0
 ; RV64I-NEXT:    ret
   %1 = sub i32 -2, %a
@@ -231,7 +229,6 @@ define i32 @sll_negative_constant_lhs(i32 %a) nounwind {
 ; RV64I-LABEL: sll_negative_constant_lhs:
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    addi a1, zero, -1
-; RV64I-NEXT:    srli a1, a1, 32
 ; RV64I-NEXT:    sllw a0, a1, a0
 ; RV64I-NEXT:    ret
   %1 = shl i32 -1, %a
@@ -310,7 +307,6 @@ define i32 @srl_negative_constant_lhs(i32 %a) nounwind {
 ; RV64I-LABEL: srl_negative_constant_lhs:
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    addi a1, zero, -1
-; RV64I-NEXT:    srli a1, a1, 32
 ; RV64I-NEXT:    srlw a0, a1, a0
 ; RV64I-NEXT:    ret
   %1 = lshr i32 -1, %a
@@ -340,8 +336,7 @@ define i32 @sra_negative_constant_lhs(i32 %a) nounwind {
 ;
 ; RV64I-LABEL: sra_negative_constant_lhs:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addi a1, zero, 1
-; RV64I-NEXT:    slli a1, a1, 31
+; RV64I-NEXT:    lui a1, 524288
 ; RV64I-NEXT:    sraw a0, a1, a0
 ; RV64I-NEXT:    ret
   %1 = ashr i32 2147483648, %a

diff  --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll
index d797fcdba8682..0addd2b26c1b9 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll
@@ -229,35 +229,28 @@ define void @rol_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind {
 define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {
 ; RV64I-LABEL: rol_i32_neg_constant_rhs:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    neg a1, a0
-; RV64I-NEXT:    addi a2, zero, 1
-; RV64I-NEXT:    slli a2, a2, 32
-; RV64I-NEXT:    addi a2, a2, -2
-; RV64I-NEXT:    srlw a1, a2, a1
-; RV64I-NEXT:    sllw a0, a2, a0
-; RV64I-NEXT:    or a0, a0, a1
+; RV64I-NEXT:    addi a1, zero, -2
+; RV64I-NEXT:    sllw a2, a1, a0
+; RV64I-NEXT:    neg a0, a0
+; RV64I-NEXT:    srlw a0, a1, a0
+; RV64I-NEXT:    or a0, a2, a0
 ; RV64I-NEXT:    ret
 ;
 ; RV64IB-LABEL: rol_i32_neg_constant_rhs:
 ; RV64IB:       # %bb.0:
 ; RV64IB-NEXT:    addi a1, zero, -2
-; RV64IB-NEXT:    zext.w a1, a1
 ; RV64IB-NEXT:    rolw a0, a1, a0
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBB-LABEL: rol_i32_neg_constant_rhs:
 ; RV64IBB:       # %bb.0:
-; RV64IBB-NEXT:    addi a1, zero, 1
-; RV64IBB-NEXT:    slli a1, a1, 32
-; RV64IBB-NEXT:    addi a1, a1, -2
+; RV64IBB-NEXT:    addi a1, zero, -2
 ; RV64IBB-NEXT:    rolw a0, a1, a0
 ; RV64IBB-NEXT:    ret
 ;
 ; RV64IBP-LABEL: rol_i32_neg_constant_rhs:
 ; RV64IBP:       # %bb.0:
-; RV64IBP-NEXT:    addi a1, zero, 1
-; RV64IBP-NEXT:    slli a1, a1, 32
-; RV64IBP-NEXT:    addi a1, a1, -2
+; RV64IBP-NEXT:    addi a1, zero, -2
 ; RV64IBP-NEXT:    rolw a0, a1, a0
 ; RV64IBP-NEXT:    ret
   %1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a)
@@ -358,35 +351,28 @@ define void @ror_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind {
 define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {
 ; RV64I-LABEL: ror_i32_neg_constant_rhs:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    neg a1, a0
-; RV64I-NEXT:    addi a2, zero, 1
-; RV64I-NEXT:    slli a2, a2, 32
-; RV64I-NEXT:    addi a2, a2, -2
-; RV64I-NEXT:    sllw a1, a2, a1
-; RV64I-NEXT:    srlw a0, a2, a0
-; RV64I-NEXT:    or a0, a0, a1
+; RV64I-NEXT:    addi a1, zero, -2
+; RV64I-NEXT:    srlw a2, a1, a0
+; RV64I-NEXT:    neg a0, a0
+; RV64I-NEXT:    sllw a0, a1, a0
+; RV64I-NEXT:    or a0, a2, a0
 ; RV64I-NEXT:    ret
 ;
 ; RV64IB-LABEL: ror_i32_neg_constant_rhs:
 ; RV64IB:       # %bb.0:
 ; RV64IB-NEXT:    addi a1, zero, -2
-; RV64IB-NEXT:    zext.w a1, a1
 ; RV64IB-NEXT:    rorw a0, a1, a0
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBB-LABEL: ror_i32_neg_constant_rhs:
 ; RV64IBB:       # %bb.0:
-; RV64IBB-NEXT:    addi a1, zero, 1
-; RV64IBB-NEXT:    slli a1, a1, 32
-; RV64IBB-NEXT:    addi a1, a1, -2
+; RV64IBB-NEXT:    addi a1, zero, -2
 ; RV64IBB-NEXT:    rorw a0, a1, a0
 ; RV64IBB-NEXT:    ret
 ;
 ; RV64IBP-LABEL: ror_i32_neg_constant_rhs:
 ; RV64IBP:       # %bb.0:
-; RV64IBP-NEXT:    addi a1, zero, 1
-; RV64IBP-NEXT:    slli a1, a1, 32
-; RV64IBP-NEXT:    addi a1, a1, -2
+; RV64IBP-NEXT:    addi a1, zero, -2
 ; RV64IBP-NEXT:    rorw a0, a1, a0
 ; RV64IBP-NEXT:    ret
   %1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a)

diff  --git a/llvm/test/CodeGen/RISCV/xaluo.ll b/llvm/test/CodeGen/RISCV/xaluo.ll
index 6ac371701a9af..dd41a94d35625 100644
--- a/llvm/test/CodeGen/RISCV/xaluo.ll
+++ b/llvm/test/CodeGen/RISCV/xaluo.ll
@@ -400,13 +400,10 @@ define zeroext i1 @uaddo.i32.constant(i32 %v1, i32* %res) {
 ;
 ; RV64-LABEL: uaddo.i32.constant:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    addi a2, zero, 1
-; RV64-NEXT:    slli a2, a2, 32
-; RV64-NEXT:    addi a3, a2, -2
-; RV64-NEXT:    addw a2, a0, a3
-; RV64-NEXT:    sext.w a4, a0
-; RV64-NEXT:    sltu a2, a2, a4
-; RV64-NEXT:    add a0, a0, a3
+; RV64-NEXT:    sext.w a2, a0
+; RV64-NEXT:    addiw a3, a0, -2
+; RV64-NEXT:    sltu a2, a3, a2
+; RV64-NEXT:    addi a0, a0, -2
 ; RV64-NEXT:    sw a0, 0(a1)
 ; RV64-NEXT:    mv a0, a2
 ; RV64-NEXT:    ret
@@ -420,12 +417,10 @@ define zeroext i1 @uaddo.i32.constant(i32 %v1, i32* %res) {
 ;
 ; RV64ZBA-LABEL: uaddo.i32.constant:
 ; RV64ZBA:       # %bb.0: # %entry
-; RV64ZBA-NEXT:    addi a2, zero, -2
-; RV64ZBA-NEXT:    zext.w a3, a2
-; RV64ZBA-NEXT:    addw a2, a0, a3
-; RV64ZBA-NEXT:    sext.w a4, a0
-; RV64ZBA-NEXT:    sltu a2, a2, a4
-; RV64ZBA-NEXT:    add a0, a0, a3
+; RV64ZBA-NEXT:    sext.w a2, a0
+; RV64ZBA-NEXT:    addiw a3, a0, -2
+; RV64ZBA-NEXT:    sltu a2, a3, a2
+; RV64ZBA-NEXT:    addi a0, a0, -2
 ; RV64ZBA-NEXT:    sw a0, 0(a1)
 ; RV64ZBA-NEXT:    mv a0, a2
 ; RV64ZBA-NEXT:    ret
@@ -685,13 +680,10 @@ define zeroext i1 @usubo.i32.constant.rhs(i32 %v1, i32* %res) {
 ;
 ; RV64-LABEL: usubo.i32.constant.rhs:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    addi a2, zero, -1
-; RV64-NEXT:    slli a2, a2, 32
-; RV64-NEXT:    addi a3, a2, 2
-; RV64-NEXT:    addw a2, a0, a3
-; RV64-NEXT:    sext.w a4, a0
-; RV64-NEXT:    sltu a2, a4, a2
-; RV64-NEXT:    add a0, a0, a3
+; RV64-NEXT:    addiw a2, a0, 2
+; RV64-NEXT:    sext.w a3, a0
+; RV64-NEXT:    sltu a2, a3, a2
+; RV64-NEXT:    addi a0, a0, 2
 ; RV64-NEXT:    sw a0, 0(a1)
 ; RV64-NEXT:    mv a0, a2
 ; RV64-NEXT:    ret
@@ -705,13 +697,10 @@ define zeroext i1 @usubo.i32.constant.rhs(i32 %v1, i32* %res) {
 ;
 ; RV64ZBA-LABEL: usubo.i32.constant.rhs:
 ; RV64ZBA:       # %bb.0: # %entry
-; RV64ZBA-NEXT:    addi a2, zero, -1
-; RV64ZBA-NEXT:    slli a2, a2, 32
-; RV64ZBA-NEXT:    addi a3, a2, 2
-; RV64ZBA-NEXT:    addw a2, a0, a3
-; RV64ZBA-NEXT:    sext.w a4, a0
-; RV64ZBA-NEXT:    sltu a2, a4, a2
-; RV64ZBA-NEXT:    add a0, a0, a3
+; RV64ZBA-NEXT:    addiw a2, a0, 2
+; RV64ZBA-NEXT:    sext.w a3, a0
+; RV64ZBA-NEXT:    sltu a2, a3, a2
+; RV64ZBA-NEXT:    addi a0, a0, 2
 ; RV64ZBA-NEXT:    sw a0, 0(a1)
 ; RV64ZBA-NEXT:    mv a0, a2
 ; RV64ZBA-NEXT:    ret
@@ -735,9 +724,7 @@ define zeroext i1 @usubo.i32.constant.lhs(i32 %v1, i32* %res) {
 ;
 ; RV64-LABEL: usubo.i32.constant.lhs:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    addi a2, zero, 1
-; RV64-NEXT:    slli a2, a2, 32
-; RV64-NEXT:    addi a3, a2, -2
+; RV64-NEXT:    addi a3, zero, -2
 ; RV64-NEXT:    subw a2, a3, a0
 ; RV64-NEXT:    addi a2, a2, 1
 ; RV64-NEXT:    seqz a2, a2
@@ -757,8 +744,7 @@ define zeroext i1 @usubo.i32.constant.lhs(i32 %v1, i32* %res) {
 ;
 ; RV64ZBA-LABEL: usubo.i32.constant.lhs:
 ; RV64ZBA:       # %bb.0: # %entry
-; RV64ZBA-NEXT:    addi a2, zero, -2
-; RV64ZBA-NEXT:    zext.w a3, a2
+; RV64ZBA-NEXT:    addi a3, zero, -2
 ; RV64ZBA-NEXT:    subw a2, a3, a0
 ; RV64ZBA-NEXT:    addi a2, a2, 1
 ; RV64ZBA-NEXT:    seqz a2, a2


        


More information about the llvm-commits mailing list