[PATCH] D137949: [RISCV] Branchless lowering for select (x < 0), TrueConstant, FalseConstant)

Liao Chunyu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 14 07:20:38 PST 2022


liaolucy created this revision.
liaolucy added reviewers: craig.topper, reames.
Herald added subscribers: sunshaoce, VincentWu, StephenFan, vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya, arichardson.
Herald added a project: All.
liaolucy requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead, eopXD, MaskRay.
Herald added a project: LLVM.

Reference gcc optimization: https://godbolt.org/z/dETnnaPK1


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137949

Files:
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/test/CodeGen/RISCV/select-const.ll


Index: llvm/test/CodeGen/RISCV/select-const.ll
===================================================================
--- llvm/test/CodeGen/RISCV/select-const.ll
+++ llvm/test/CodeGen/RISCV/select-const.ll
@@ -391,3 +391,24 @@
   %2 = select i1 %1, i32 10001, i32 10002
   ret i32 %2
 }
+
+define i32 @select_slt_zero_constant1_constant2(i32 signext %x) {
+; RV32-LABEL: select_slt_zero_constant1_constant2:
+; RV32:       # %bb.0:
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    srai a0, a0, 31
+; RV32-NEXT:    andi a0, a0, -10
+; RV32-NEXT:    addi a0, a0, 7
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: select_slt_zero_constant1_constant2:
+; RV64:       # %bb.0:
+; RV64-NEXT:    not a0, a0
+; RV64-NEXT:    srai a0, a0, 63
+; RV64-NEXT:    andi a0, a0, -10
+; RV64-NEXT:    addi a0, a0, 7
+; RV64-NEXT:    ret
+  %cmp = icmp slt i32 %x, 0
+  %cond = select i1 %cmp, i32 7, i32 -3
+  ret i32 %cond
+}
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9627,6 +9627,30 @@
       }
     }
 
+    // select (x < 0), y, z) -> (~x >> (XLEN - 1)) & (z - y) + y
+    APInt RMask = APInt::getBitsSetFrom(RHS.getValueSizeInBits(), 1);
+    if (!Subtarget.hasShortForwardBranchOpt() &&
+        CCVal == ISD::CondCode::SETLT && DAG.MaskedValueIsZero(RHS, RMask) &&
+        isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
+      int64_t TrueSImm = cast<ConstantSDNode>(TrueV)->getSExtValue();
+      int64_t FalseSImm = cast<ConstantSDNode>(FalseV)->getSExtValue();
+      // Only handle simm12, if it is not in this range, it can be considered as
+      // register.
+      if (isInt<12>((uint64_t)TrueSImm) && isInt<12>((uint64_t)FalseSImm) &&
+          isInt<12>((uint64_t)FalseSImm - (uint64_t)TrueSImm)) {
+        SDValue XOR = DAG.getNOT(DL, LHS, VT);
+        SDValue SRA;
+        if (Subtarget.is64Bit())
+          SRA = DAG.getNode(ISD::SRA, DL, VT, XOR, DAG.getConstant(63, DL, VT));
+        else
+          SRA = DAG.getNode(ISD::SRA, DL, VT, XOR, DAG.getConstant(31, DL, VT));
+        SDValue AND =
+            DAG.getNode(ISD::AND, DL, VT, SRA,
+                        DAG.getConstant(FalseSImm - TrueSImm, DL, VT));
+        return DAG.getNode(ISD::ADD, DL, VT, AND, TrueV);
+      }
+    }
+
     if (combine_CC(LHS, RHS, CC, DL, DAG, Subtarget))
       return DAG.getNode(RISCVISD::SELECT_CC, DL, N->getValueType(0),
                          {LHS, RHS, CC, TrueV, FalseV});


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D137949.475143.patch
Type: text/x-patch
Size: 2563 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221114/6f3e3295/attachment.bin>


More information about the llvm-commits mailing list