]> granicus.if.org Git - llvm/commitdiff
[RISCV] Improve codegen for icmp {ne,eq} with a constant
authorLuis Marques <luismarques@lowrisc.org>
Tue, 26 Mar 2019 12:55:00 +0000 (12:55 +0000)
committerLuis Marques <luismarques@lowrisc.org>
Tue, 26 Mar 2019 12:55:00 +0000 (12:55 +0000)
Adds two patterns to improve the codegen of GPR value comparisons with small
constants. Instead of first loading the constant into another register and then
doing an XOR of those registers, these patterns directly use the constant as an
XORI immediate.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356990 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/RISCV/RISCVInstrInfo.td
test/CodeGen/RISCV/i32-icmp.ll

index 296e736ab10a1e683a849a43d6602a6353ec0d59..dce704cce1034d1bbf906b9b6080a9808ec79c88 100644 (file)
@@ -771,8 +771,12 @@ def : PatGprSimm12<setult, SLTIU>;
 // handled by a RISC-V instruction.
 def : Pat<(seteq GPR:$rs1, 0), (SLTIU GPR:$rs1, 1)>;
 def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
+def : Pat<(seteq GPR:$rs1, simm12:$imm12),
+          (SLTIU (XORI GPR:$rs1, simm12:$imm12), 1)>;
 def : Pat<(setne GPR:$rs1, 0), (SLTU X0, GPR:$rs1)>;
 def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
+def : Pat<(setne GPR:$rs1, simm12:$imm12),
+          (SLTU X0, (XORI GPR:$rs1, simm12:$imm12))>;
 def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>;
 def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
 def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
index 3b89504bbc02effb2539fb2e19224ffe6c7e92b4..04b1eeaad21a0d648b8e0367cc949e7ce918c714 100644 (file)
@@ -16,6 +16,17 @@ define i32 @icmp_eq(i32 %a, i32 %b) nounwind {
   ret i32 %2
 }
 
+define i32 @icmp_eq_constant(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    xori a0, a0, 42
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp eq i32 %a, 42
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_eqz(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_eqz:
 ; RV32I:       # %bb.0:
@@ -37,6 +48,17 @@ define i32 @icmp_ne(i32 %a, i32 %b) nounwind {
   ret i32 %2
 }
 
+define i32 @icmp_ne_constant(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ne_constant:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    xori a0, a0, 42
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp ne i32 %a, 42
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_nez(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_nez:
 ; RV32I:       # %bb.0: