[PATCH] D149814: [RISCV] Optimize i32 range checks
Yingwei Zheng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 3 22:10:18 PDT 2023
dtcxzyw created this revision.
dtcxzyw added a reviewer: craig.topper.
Herald added subscribers: jobnoorman, luke, VincentWu, 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.
dtcxzyw requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead, eopXD, MaskRay.
Herald added a project: LLVM.
This patch improves instruction selection for i32 range check patterns like `INT_MIN <= x && x <= INT_MAX` and its alternatives.
On rv32: GCC: https://godbolt.org/z/1zKjfMqax Alive2: https://alive2.llvm.org/ce/z/FPc4ss
On rv64: GCC: https://godbolt.org/z/ezTsv8cEo Alive2: https://alive2.llvm.org/ce/z/ZkF7Er
I am unsure whether it is suitable to do the pattern match in ISel. I also have an alternative <https://github.com/llvm/llvm-project/compare/main...dtcxzyw:llvm-project:i32-range-check> that does pattern match in `RISCVCodeGenPrepare`.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D149814
Files:
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/test/CodeGen/RISCV/setcc-logic.ll
Index: llvm/test/CodeGen/RISCV/setcc-logic.ll
===================================================================
--- llvm/test/CodeGen/RISCV/setcc-logic.ll
+++ llvm/test/CodeGen/RISCV/setcc-logic.ll
@@ -1322,3 +1322,23 @@
8: ; preds = %8, %4
ret void
}
+
+define i32 @i32_range_check(i64 %0) {
+; RV32I-LABEL: i32_range_check:
+; RV32I: # %bb.0:
+; RV32I-NEXT: srai a0, a0, 31
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: seqz a0, a0
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: i32_range_check:
+; RV64I: # %bb.0:
+; RV64I-NEXT: sext.w a1, a0
+; RV64I-NEXT: xor a0, a0, a1
+; RV64I-NEXT: seqz a0, a0
+; RV64I-NEXT: ret
+ %2 = add i64 %0, 2147483648
+ %3 = icmp ult i64 %2, 4294967296
+ %4 = zext i1 %3 to i32
+ ret i32 %4
+}
Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1242,6 +1242,7 @@
def and_oneuse : binop_oneuse<and>;
def add_oneuse : binop_oneuse<add>;
def mul_oneuse : binop_oneuse<mul>;
+def srl_oneuse : binop_oneuse<srl>;
def mul_const_oneuse : PatFrag<(ops node:$A, node:$B),
(mul node:$A, node:$B), [{
@@ -1367,6 +1368,18 @@
def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;
def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;
+// i32 range checks
+let Predicates = [IsRV64] in {
+// Select ADDIW on rv64
+def : Pat<(seteq (srl_oneuse (add_oneuse GPR:$rs1, (i64 2147483648)), (i64 32)), (i64 0)),
+ (SLTIU (XOR $rs1, (ADDIW $rs1, 0)), 1)>;
+}
+let Predicates = [IsRV32] in {
+// Select SRAI on rv32
+def : Pat<(seteq (add_oneuse GPR:$rs1, (binop_oneuse<setult> (add_oneuse GPR:$rs2, (i32 -2147483648)), GPR:$rs2)), (i32 0)),
+ (SLTIU (XOR (SRAI $rs2, 31), $rs1), 1)>;
+}
+
// Define pattern expansions for setcc operations that aren't directly
// handled by a RISC-V instruction.
def : Pat<(riscv_seteq GPR:$rs1), (SLTIU GPR:$rs1, 1)>;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149814.519355.patch
Type: text/x-patch
Size: 2097 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230504/2d58a634/attachment.bin>
More information about the llvm-commits
mailing list