[llvm] 548fa1d - [RISCV] Add special case for (select cc, 1.0, 0.0) to lowerSELECT

via llvm-commits llvm-commits at lists.llvm.org
Wed May 31 00:21:02 PDT 2023


Author: LiaoChunyu
Date: 2023-05-31T15:20:57+08:00
New Revision: 548fa1d3086f5fe6e6e1bf52bb661e00a954503e

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

LOG: [RISCV] Add special case for (select cc, 1.0, 0.0) to lowerSELECT

Use sint_to_fp instead of select.
Reduce the number of branch instructions and
avoid generating TargetConstantPool for double.

(select cc, 1.0, 0.0) -> (sint_to_fp (zext cc))
https://alive2.llvm.org/ce/z/aoEcd9
https://godbolt.org/z/n543Y9v3e

(select cc, 0.0, 1.0) -> (sint_to_fp (zext (xor cc, 1)))
https://alive2.llvm.org/ce/z/zngvSB

Reviewed By: craig.topper

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/double-select-icmp.ll
    llvm/test/CodeGen/RISCV/float-select-icmp.ll
    llvm/test/CodeGen/RISCV/half-select-icmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c327bc51d771..305ad5896365 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -5512,6 +5512,20 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
   if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
     return V;
 
+  // (select cc, 1.0, 0.0) -> (sint_to_fp (zext cc))
+  // (select cc, 0.0, 1.0) -> (sint_to_fp (zext (xor cc, 1)))
+  const ConstantFPSDNode *FPTV = dyn_cast<ConstantFPSDNode>(TrueV);
+  const ConstantFPSDNode *FPFV = dyn_cast<ConstantFPSDNode>(FalseV);
+  if (FPTV && FPFV) {
+    if (FPTV->isExactlyValue(1.0) && FPFV->isExactlyValue(0.0))
+      return DAG.getNode(ISD::SINT_TO_FP, DL, VT, CondV);
+    if (FPTV->isExactlyValue(0.0) && FPFV->isExactlyValue(1.0)) {
+      SDValue XOR = DAG.getNode(ISD::XOR, DL, XLenVT, CondV,
+                                DAG.getConstant(1, DL, XLenVT));
+      return DAG.getNode(ISD::SINT_TO_FP, DL, VT, XOR);
+    }
+  }
+
   // If the condition is not an integer SETCC which operates on XLenVT, we need
   // to emit a RISCVISD::SELECT_CC comparing the condition to zero. i.e.:
   // (select condv, truev, falsev)

diff  --git a/llvm/test/CodeGen/RISCV/double-select-icmp.ll b/llvm/test/CodeGen/RISCV/double-select-icmp.ll
index 259ba6a2b500..9fdab5f7b8a5 100644
--- a/llvm/test/CodeGen/RISCV/double-select-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/double-select-icmp.ll
@@ -448,3 +448,67 @@ define double @select_icmp_sle(i32 signext %a, i32 signext %b, double %c, double
   %2 = select i1 %1, double %c, double %d
   ret double %2
 }
+
+define double @select_icmp_slt_one(i32 signext %a) {
+; CHECK-LABEL: select_icmp_slt_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slti a0, a0, 1
+; CHECK-NEXT:    fcvt.d.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; RV32ZDINX-LABEL: select_icmp_slt_one:
+; RV32ZDINX:       # %bb.0:
+; RV32ZDINX-NEXT:    addi sp, sp, -16
+; RV32ZDINX-NEXT:    .cfi_def_cfa_offset 16
+; RV32ZDINX-NEXT:    slti a0, a0, 1
+; RV32ZDINX-NEXT:    fcvt.d.w a0, a0
+; RV32ZDINX-NEXT:    sw a0, 8(sp)
+; RV32ZDINX-NEXT:    sw a1, 12(sp)
+; RV32ZDINX-NEXT:    lw a0, 8(sp)
+; RV32ZDINX-NEXT:    lw a1, 12(sp)
+; RV32ZDINX-NEXT:    addi sp, sp, 16
+; RV32ZDINX-NEXT:    ret
+;
+; RV64ZDINX-LABEL: select_icmp_slt_one:
+; RV64ZDINX:       # %bb.0:
+; RV64ZDINX-NEXT:    slti a0, a0, 1
+; RV64ZDINX-NEXT:    fcvt.d.w a0, a0
+; RV64ZDINX-NEXT:    ret
+  %1 = icmp slt i32 %a, 1
+  %2 = select i1 %1, double 1.000000e+00, double 0.000000e+00
+  ret double %2
+}
+
+define double @select_icmp_sgt_zero(i32 signext %a) {
+; CHECK-LABEL: select_icmp_sgt_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    sgtz a0, a0
+; CHECK-NEXT:    xori a0, a0, 1
+; CHECK-NEXT:    fcvt.d.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; RV32ZDINX-LABEL: select_icmp_sgt_zero:
+; RV32ZDINX:       # %bb.0:
+; RV32ZDINX-NEXT:    addi sp, sp, -16
+; RV32ZDINX-NEXT:    .cfi_def_cfa_offset 16
+; RV32ZDINX-NEXT:    sgtz a0, a0
+; RV32ZDINX-NEXT:    xori a0, a0, 1
+; RV32ZDINX-NEXT:    fcvt.d.w a0, a0
+; RV32ZDINX-NEXT:    sw a0, 8(sp)
+; RV32ZDINX-NEXT:    sw a1, 12(sp)
+; RV32ZDINX-NEXT:    lw a0, 8(sp)
+; RV32ZDINX-NEXT:    lw a1, 12(sp)
+; RV32ZDINX-NEXT:    addi sp, sp, 16
+; RV32ZDINX-NEXT:    ret
+;
+; RV64ZDINX-LABEL: select_icmp_sgt_zero:
+; RV64ZDINX:       # %bb.0:
+; RV64ZDINX-NEXT:    sgtz a0, a0
+; RV64ZDINX-NEXT:    xori a0, a0, 1
+; RV64ZDINX-NEXT:    fcvt.d.w a0, a0
+; RV64ZDINX-NEXT:    ret
+  %1 = icmp sgt i32 %a, 0
+  %2 = select i1 %1, double 0.000000e+00, double 1.000000e+00
+  ret double %2
+}
+

diff  --git a/llvm/test/CodeGen/RISCV/float-select-icmp.ll b/llvm/test/CodeGen/RISCV/float-select-icmp.ll
index f46f25f777ca..1d2aeaaf917d 100644
--- a/llvm/test/CodeGen/RISCV/float-select-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/float-select-icmp.ll
@@ -227,3 +227,39 @@ define float @select_icmp_sle(i32 signext %a, i32 signext %b, float %c, float %d
   %2 = select i1 %1, float %c, float %d
   ret float %2
 }
+
+define float @select_icmp_slt_one(i32 signext %a) {
+; CHECK-LABEL: select_icmp_slt_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slti a0, a0, 1
+; CHECK-NEXT:    fcvt.s.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; CHECKZFINX-LABEL: select_icmp_slt_one:
+; CHECKZFINX:       # %bb.0:
+; CHECKZFINX-NEXT:    slti a0, a0, 1
+; CHECKZFINX-NEXT:    fcvt.s.w a0, a0
+; CHECKZFINX-NEXT:    ret
+  %1 = icmp slt i32 %a, 1
+  %2 = select i1 %1, float 1.000000e+00, float 0.000000e+00
+  ret float %2
+}
+
+define float @select_icmp_sgt_zero(i32 signext %a) {
+; CHECK-LABEL: select_icmp_sgt_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    sgtz a0, a0
+; CHECK-NEXT:    xori a0, a0, 1
+; CHECK-NEXT:    fcvt.s.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; CHECKZFINX-LABEL: select_icmp_sgt_zero:
+; CHECKZFINX:       # %bb.0:
+; CHECKZFINX-NEXT:    sgtz a0, a0
+; CHECKZFINX-NEXT:    xori a0, a0, 1
+; CHECKZFINX-NEXT:    fcvt.s.w a0, a0
+; CHECKZFINX-NEXT:    ret
+  %1 = icmp sgt i32 %a, 0
+  %2 = select i1 %1, float 0.000000e+00, float 1.000000e+00
+  ret float %2
+}

diff  --git a/llvm/test/CodeGen/RISCV/half-select-icmp.ll b/llvm/test/CodeGen/RISCV/half-select-icmp.ll
index 921ca184745b..465579abe4a8 100644
--- a/llvm/test/CodeGen/RISCV/half-select-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/half-select-icmp.ll
@@ -475,3 +475,70 @@ define half @select_icmp_sle(i32 signext %a, i32 signext %b, half %c, half %d) {
   %2 = select i1 %1, half %c, half %d
   ret half %2
 }
+
+define half @select_icmp_slt_one(i32 signext %a) {
+; CHECK-LABEL: select_icmp_slt_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slti a0, a0, 1
+; CHECK-NEXT:    fcvt.h.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; CHECKIZHINX-LABEL: select_icmp_slt_one:
+; CHECKIZHINX:       # %bb.0:
+; CHECKIZHINX-NEXT:    slti a0, a0, 1
+; CHECKIZHINX-NEXT:    fcvt.h.w a0, a0
+; CHECKIZHINX-NEXT:    ret
+;
+; CHECKIZFHMIN-LABEL: select_icmp_slt_one:
+; CHECKIZFHMIN:       # %bb.0:
+; CHECKIZFHMIN-NEXT:    slti a0, a0, 1
+; CHECKIZFHMIN-NEXT:    fcvt.s.w fa5, a0
+; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; CHECKIZFHMIN-NEXT:    ret
+;
+; CHECKIZHINXMIN-LABEL: select_icmp_slt_one:
+; CHECKIZHINXMIN:       # %bb.0:
+; CHECKIZHINXMIN-NEXT:    slti a0, a0, 1
+; CHECKIZHINXMIN-NEXT:    fcvt.s.w a0, a0
+; CHECKIZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; CHECKIZHINXMIN-NEXT:    ret
+  %1 = icmp slt i32 %a, 1
+  %2 = select i1 %1, half 1.000000e+00, half 0.000000e+00
+  ret half %2
+}
+
+define half @select_icmp_sgt_zero(i32 signext %a) {
+; CHECK-LABEL: select_icmp_sgt_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    sgtz a0, a0
+; CHECK-NEXT:    xori a0, a0, 1
+; CHECK-NEXT:    fcvt.h.w fa0, a0
+; CHECK-NEXT:    ret
+;
+; CHECKIZHINX-LABEL: select_icmp_sgt_zero:
+; CHECKIZHINX:       # %bb.0:
+; CHECKIZHINX-NEXT:    sgtz a0, a0
+; CHECKIZHINX-NEXT:    xori a0, a0, 1
+; CHECKIZHINX-NEXT:    fcvt.h.w a0, a0
+; CHECKIZHINX-NEXT:    ret
+;
+; CHECKIZFHMIN-LABEL: select_icmp_sgt_zero:
+; CHECKIZFHMIN:       # %bb.0:
+; CHECKIZFHMIN-NEXT:    sgtz a0, a0
+; CHECKIZFHMIN-NEXT:    xori a0, a0, 1
+; CHECKIZFHMIN-NEXT:    fcvt.s.w fa5, a0
+; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; CHECKIZFHMIN-NEXT:    ret
+;
+; CHECKIZHINXMIN-LABEL: select_icmp_sgt_zero:
+; CHECKIZHINXMIN:       # %bb.0:
+; CHECKIZHINXMIN-NEXT:    sgtz a0, a0
+; CHECKIZHINXMIN-NEXT:    xori a0, a0, 1
+; CHECKIZHINXMIN-NEXT:    fcvt.s.w a0, a0
+; CHECKIZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; CHECKIZHINXMIN-NEXT:    ret
+  %1 = icmp sgt i32 %a, 0
+  %2 = select i1 %1, half 0.000000e+00, half 1.000000e+00
+  ret half %2
+}
+


        


More information about the llvm-commits mailing list