[llvm-branch-commits] [llvm] 751b0d9 - [RISCV] Make SMIN/SMAX/UMIN/UMAX legal with Zbb extension.

Craig Topper via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Nov 25 12:53:45 PST 2020


Author: Craig Topper
Date: 2020-11-25T12:48:43-08:00
New Revision: 751b0d970e757aef055fb6e1a981a7c44185aa80

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

LOG: [RISCV] Make SMIN/SMAX/UMIN/UMAX legal with Zbb extension.

This is the logically correct thing to do. But it generates worse
code for i32 umin/umax on the rv64 due to type legalize requesting
zext even though the arguments are sext. Maybe we can teach type
legalizer to use sext for umin/umax for RISCV.

It's also producing possibly worse code on i64 on RV32 since we
still end up with selects that become branches. But this seems
like something we could improve in type legalization or DAG combine.

Hopefully this makes D92095 work for RISCV with Zbb.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfoB.td
    llvm/test/CodeGen/RISCV/rv32Zbb.ll
    llvm/test/CodeGen/RISCV/rv64Zbb.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 854e0f4162b2..c182a34c0c9a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -172,7 +172,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::BSWAP, XLenVT, Expand);
   }
 
-  if (!Subtarget.hasStdExtZbb()) {
+  if (Subtarget.hasStdExtZbb()) {
+    setOperationAction(ISD::SMIN, XLenVT, Legal);
+    setOperationAction(ISD::SMAX, XLenVT, Legal);
+    setOperationAction(ISD::UMIN, XLenVT, Legal);
+    setOperationAction(ISD::UMAX, XLenVT, Legal);
+  } else {
     setOperationAction(ISD::CTTZ, XLenVT, Expand);
     setOperationAction(ISD::CTLZ, XLenVT, Expand);
     setOperationAction(ISD::CTPOP, XLenVT, Expand);

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
index b97306c459ad..29ccffb05cfd 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -789,17 +789,9 @@ def : Pat<(sext_inreg GPR:$rs1, i16), (SEXTH GPR:$rs1)>;
 
 let Predicates = [HasStdExtZbb] in {
 def : Pat<(smin GPR:$rs1, GPR:$rs2), (MIN  GPR:$rs1, GPR:$rs2)>;
-def : Pat<(riscv_selectcc GPR:$rs1, GPR:$rs2, (XLenVT 20), GPR:$rs1, GPR:$rs2),
-          (MIN  GPR:$rs1, GPR:$rs2)>;
 def : Pat<(smax GPR:$rs1, GPR:$rs2), (MAX  GPR:$rs1, GPR:$rs2)>;
-def : Pat<(riscv_selectcc GPR:$rs2, GPR:$rs1, (XLenVT 20), GPR:$rs1, GPR:$rs2),
-          (MAX  GPR:$rs1, GPR:$rs2)>;
 def : Pat<(umin GPR:$rs1, GPR:$rs2), (MINU GPR:$rs1, GPR:$rs2)>;
-def : Pat<(riscv_selectcc GPR:$rs1, GPR:$rs2, (XLenVT 12), GPR:$rs1, GPR:$rs2),
-          (MINU  GPR:$rs1, GPR:$rs2)>;
 def : Pat<(umax GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>;
-def : Pat<(riscv_selectcc GPR:$rs2, GPR:$rs1, (XLenVT 12), GPR:$rs1, GPR:$rs2),
-          (MAXU  GPR:$rs1, GPR:$rs2)>;
 } // Predicates = [HasStdExtZbb]
 
 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in

diff  --git a/llvm/test/CodeGen/RISCV/rv32Zbb.ll b/llvm/test/CodeGen/RISCV/rv32Zbb.ll
index 8da1fe64c65f..d67bc0cc667a 100644
--- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll
@@ -910,34 +910,36 @@ define i64 @min_i64(i64 %a, i64 %b) nounwind {
 ;
 ; RV32IB-LABEL: min_i64:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    beq a1, a3, .LBB19_2
+; RV32IB-NEXT:    mv a4, a0
+; RV32IB-NEXT:    bge a1, a3, .LBB19_3
 ; RV32IB-NEXT:  # %bb.1:
-; RV32IB-NEXT:    slt a4, a1, a3
-; RV32IB-NEXT:    beqz a4, .LBB19_3
-; RV32IB-NEXT:    j .LBB19_4
+; RV32IB-NEXT:    beq a1, a3, .LBB19_4
 ; RV32IB-NEXT:  .LBB19_2:
-; RV32IB-NEXT:    sltu a4, a0, a2
-; RV32IB-NEXT:    bnez a4, .LBB19_4
+; RV32IB-NEXT:    min a1, a1, a3
+; RV32IB-NEXT:    ret
 ; RV32IB-NEXT:  .LBB19_3:
 ; RV32IB-NEXT:    mv a0, a2
-; RV32IB-NEXT:    mv a1, a3
+; RV32IB-NEXT:    bne a1, a3, .LBB19_2
 ; RV32IB-NEXT:  .LBB19_4:
+; RV32IB-NEXT:    minu a0, a4, a2
+; RV32IB-NEXT:    min a1, a1, a3
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBB-LABEL: min_i64:
 ; RV32IBB:       # %bb.0:
-; RV32IBB-NEXT:    beq a1, a3, .LBB19_2
+; RV32IBB-NEXT:    mv a4, a0
+; RV32IBB-NEXT:    bge a1, a3, .LBB19_3
 ; RV32IBB-NEXT:  # %bb.1:
-; RV32IBB-NEXT:    slt a4, a1, a3
-; RV32IBB-NEXT:    beqz a4, .LBB19_3
-; RV32IBB-NEXT:    j .LBB19_4
+; RV32IBB-NEXT:    beq a1, a3, .LBB19_4
 ; RV32IBB-NEXT:  .LBB19_2:
-; RV32IBB-NEXT:    sltu a4, a0, a2
-; RV32IBB-NEXT:    bnez a4, .LBB19_4
+; RV32IBB-NEXT:    min a1, a1, a3
+; RV32IBB-NEXT:    ret
 ; RV32IBB-NEXT:  .LBB19_3:
 ; RV32IBB-NEXT:    mv a0, a2
-; RV32IBB-NEXT:    mv a1, a3
+; RV32IBB-NEXT:    bne a1, a3, .LBB19_2
 ; RV32IBB-NEXT:  .LBB19_4:
+; RV32IBB-NEXT:    minu a0, a4, a2
+; RV32IBB-NEXT:    min a1, a1, a3
 ; RV32IBB-NEXT:    ret
   %cmp = icmp slt i64 %a, %b
   %cond = select i1 %cmp, i64 %a, i64 %b
@@ -991,34 +993,36 @@ define i64 @max_i64(i64 %a, i64 %b) nounwind {
 ;
 ; RV32IB-LABEL: max_i64:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    beq a1, a3, .LBB21_2
+; RV32IB-NEXT:    mv a4, a0
+; RV32IB-NEXT:    bge a3, a1, .LBB21_3
 ; RV32IB-NEXT:  # %bb.1:
-; RV32IB-NEXT:    slt a4, a3, a1
-; RV32IB-NEXT:    beqz a4, .LBB21_3
-; RV32IB-NEXT:    j .LBB21_4
+; RV32IB-NEXT:    beq a1, a3, .LBB21_4
 ; RV32IB-NEXT:  .LBB21_2:
-; RV32IB-NEXT:    sltu a4, a2, a0
-; RV32IB-NEXT:    bnez a4, .LBB21_4
+; RV32IB-NEXT:    max a1, a1, a3
+; RV32IB-NEXT:    ret
 ; RV32IB-NEXT:  .LBB21_3:
 ; RV32IB-NEXT:    mv a0, a2
-; RV32IB-NEXT:    mv a1, a3
+; RV32IB-NEXT:    bne a1, a3, .LBB21_2
 ; RV32IB-NEXT:  .LBB21_4:
+; RV32IB-NEXT:    maxu a0, a4, a2
+; RV32IB-NEXT:    max a1, a1, a3
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBB-LABEL: max_i64:
 ; RV32IBB:       # %bb.0:
-; RV32IBB-NEXT:    beq a1, a3, .LBB21_2
+; RV32IBB-NEXT:    mv a4, a0
+; RV32IBB-NEXT:    bge a3, a1, .LBB21_3
 ; RV32IBB-NEXT:  # %bb.1:
-; RV32IBB-NEXT:    slt a4, a3, a1
-; RV32IBB-NEXT:    beqz a4, .LBB21_3
-; RV32IBB-NEXT:    j .LBB21_4
+; RV32IBB-NEXT:    beq a1, a3, .LBB21_4
 ; RV32IBB-NEXT:  .LBB21_2:
-; RV32IBB-NEXT:    sltu a4, a2, a0
-; RV32IBB-NEXT:    bnez a4, .LBB21_4
+; RV32IBB-NEXT:    max a1, a1, a3
+; RV32IBB-NEXT:    ret
 ; RV32IBB-NEXT:  .LBB21_3:
 ; RV32IBB-NEXT:    mv a0, a2
-; RV32IBB-NEXT:    mv a1, a3
+; RV32IBB-NEXT:    bne a1, a3, .LBB21_2
 ; RV32IBB-NEXT:  .LBB21_4:
+; RV32IBB-NEXT:    maxu a0, a4, a2
+; RV32IBB-NEXT:    max a1, a1, a3
 ; RV32IBB-NEXT:    ret
   %cmp = icmp sgt i64 %a, %b
   %cond = select i1 %cmp, i64 %a, i64 %b
@@ -1072,34 +1076,36 @@ define i64 @minu_i64(i64 %a, i64 %b) nounwind {
 ;
 ; RV32IB-LABEL: minu_i64:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    beq a1, a3, .LBB23_2
+; RV32IB-NEXT:    mv a4, a0
+; RV32IB-NEXT:    bgeu a1, a3, .LBB23_3
 ; RV32IB-NEXT:  # %bb.1:
-; RV32IB-NEXT:    sltu a4, a1, a3
-; RV32IB-NEXT:    beqz a4, .LBB23_3
-; RV32IB-NEXT:    j .LBB23_4
+; RV32IB-NEXT:    beq a1, a3, .LBB23_4
 ; RV32IB-NEXT:  .LBB23_2:
-; RV32IB-NEXT:    sltu a4, a0, a2
-; RV32IB-NEXT:    bnez a4, .LBB23_4
+; RV32IB-NEXT:    minu a1, a1, a3
+; RV32IB-NEXT:    ret
 ; RV32IB-NEXT:  .LBB23_3:
 ; RV32IB-NEXT:    mv a0, a2
-; RV32IB-NEXT:    mv a1, a3
+; RV32IB-NEXT:    bne a1, a3, .LBB23_2
 ; RV32IB-NEXT:  .LBB23_4:
+; RV32IB-NEXT:    minu a0, a4, a2
+; RV32IB-NEXT:    minu a1, a1, a3
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBB-LABEL: minu_i64:
 ; RV32IBB:       # %bb.0:
-; RV32IBB-NEXT:    beq a1, a3, .LBB23_2
+; RV32IBB-NEXT:    mv a4, a0
+; RV32IBB-NEXT:    bgeu a1, a3, .LBB23_3
 ; RV32IBB-NEXT:  # %bb.1:
-; RV32IBB-NEXT:    sltu a4, a1, a3
-; RV32IBB-NEXT:    beqz a4, .LBB23_3
-; RV32IBB-NEXT:    j .LBB23_4
+; RV32IBB-NEXT:    beq a1, a3, .LBB23_4
 ; RV32IBB-NEXT:  .LBB23_2:
-; RV32IBB-NEXT:    sltu a4, a0, a2
-; RV32IBB-NEXT:    bnez a4, .LBB23_4
+; RV32IBB-NEXT:    minu a1, a1, a3
+; RV32IBB-NEXT:    ret
 ; RV32IBB-NEXT:  .LBB23_3:
 ; RV32IBB-NEXT:    mv a0, a2
-; RV32IBB-NEXT:    mv a1, a3
+; RV32IBB-NEXT:    bne a1, a3, .LBB23_2
 ; RV32IBB-NEXT:  .LBB23_4:
+; RV32IBB-NEXT:    minu a0, a4, a2
+; RV32IBB-NEXT:    minu a1, a1, a3
 ; RV32IBB-NEXT:    ret
   %cmp = icmp ult i64 %a, %b
   %cond = select i1 %cmp, i64 %a, i64 %b
@@ -1153,34 +1159,36 @@ define i64 @maxu_i64(i64 %a, i64 %b) nounwind {
 ;
 ; RV32IB-LABEL: maxu_i64:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    beq a1, a3, .LBB25_2
+; RV32IB-NEXT:    mv a4, a0
+; RV32IB-NEXT:    bgeu a3, a1, .LBB25_3
 ; RV32IB-NEXT:  # %bb.1:
-; RV32IB-NEXT:    sltu a4, a3, a1
-; RV32IB-NEXT:    beqz a4, .LBB25_3
-; RV32IB-NEXT:    j .LBB25_4
+; RV32IB-NEXT:    beq a1, a3, .LBB25_4
 ; RV32IB-NEXT:  .LBB25_2:
-; RV32IB-NEXT:    sltu a4, a2, a0
-; RV32IB-NEXT:    bnez a4, .LBB25_4
+; RV32IB-NEXT:    maxu a1, a1, a3
+; RV32IB-NEXT:    ret
 ; RV32IB-NEXT:  .LBB25_3:
 ; RV32IB-NEXT:    mv a0, a2
-; RV32IB-NEXT:    mv a1, a3
+; RV32IB-NEXT:    bne a1, a3, .LBB25_2
 ; RV32IB-NEXT:  .LBB25_4:
+; RV32IB-NEXT:    maxu a0, a4, a2
+; RV32IB-NEXT:    maxu a1, a1, a3
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBB-LABEL: maxu_i64:
 ; RV32IBB:       # %bb.0:
-; RV32IBB-NEXT:    beq a1, a3, .LBB25_2
+; RV32IBB-NEXT:    mv a4, a0
+; RV32IBB-NEXT:    bgeu a3, a1, .LBB25_3
 ; RV32IBB-NEXT:  # %bb.1:
-; RV32IBB-NEXT:    sltu a4, a3, a1
-; RV32IBB-NEXT:    beqz a4, .LBB25_3
-; RV32IBB-NEXT:    j .LBB25_4
+; RV32IBB-NEXT:    beq a1, a3, .LBB25_4
 ; RV32IBB-NEXT:  .LBB25_2:
-; RV32IBB-NEXT:    sltu a4, a2, a0
-; RV32IBB-NEXT:    bnez a4, .LBB25_4
+; RV32IBB-NEXT:    maxu a1, a1, a3
+; RV32IBB-NEXT:    ret
 ; RV32IBB-NEXT:  .LBB25_3:
 ; RV32IBB-NEXT:    mv a0, a2
-; RV32IBB-NEXT:    mv a1, a3
+; RV32IBB-NEXT:    bne a1, a3, .LBB25_2
 ; RV32IBB-NEXT:  .LBB25_4:
+; RV32IBB-NEXT:    maxu a0, a4, a2
+; RV32IBB-NEXT:    maxu a1, a1, a3
 ; RV32IBB-NEXT:    ret
   %cmp = icmp ugt i64 %a, %b
   %cond = select i1 %cmp, i64 %a, i64 %b

diff  --git a/llvm/test/CodeGen/RISCV/rv64Zbb.ll b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
index 66985c565370..da072a171728 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
@@ -856,12 +856,18 @@ 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
@@ -902,12 +908,18 @@ 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-branch-commits mailing list