[llvm] db875f6 - [RISCV] Optimize seteq/setne pattern expansions for better code size

Andrew Wei via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 11 06:46:15 PST 2020


Author: Andrew Wei
Date: 2020-02-11T22:45:15+08:00
New Revision: db875f66554455f4957881d373987472b3071f65

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

LOG: [RISCV] Optimize seteq/setne pattern expansions for better code size

ADDI(C.ADDI) may achieve better code size than XORI, since XORI has no C extension.
This patch transforms two patterns and gets almost equivalent results.

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/CodeGen/RISCV/i32-icmp.ll
    llvm/test/CodeGen/RISCV/setcc-logic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 565fbdcfde69..71ab423cbbc9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -144,6 +144,20 @@ def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
   let OperandNamespace = "RISCVOp";
 }
 
+// A 12-bit signed immediate plus one where the imm range will be -2047~2048.
+def simm12_plus1 : Operand<XLenVT>, ImmLeaf<XLenVT,
+  [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]> {
+  let ParserMatchClass = SImmAsmOperand<12>;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<12>";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (MCOp.evaluateAsConstantImm(Imm))
+      return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;
+    return MCOp.isBareSymbolRef();
+  }];
+}
+
 // A 13-bit signed immediate where the least significant bit is zero.
 def simm13_lsb0 : Operand<OtherVT> {
   let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
@@ -296,6 +310,12 @@ def HI20 : SDNodeXForm<imm, [{
                                    SDLoc(N), N->getValueType(0));
 }]>;
 
+// Return the negation of an immediate value.
+def NegImm : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N),
+                                   N->getValueType(0));
+}]>;
+
 //===----------------------------------------------------------------------===//
 // Instruction Formats
 //===----------------------------------------------------------------------===//
@@ -857,12 +877,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<(seteq GPR:$rs1, simm12_plus1:$imm12),
+          (SLTIU (ADDI GPR:$rs1, (NegImm simm12_plus1:$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<(setne GPR:$rs1, simm12_plus1:$imm12),
+          (SLTU X0, (ADDI GPR:$rs1, (NegImm simm12_plus1:$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)>;

diff  --git a/llvm/test/CodeGen/RISCV/i32-icmp.ll b/llvm/test/CodeGen/RISCV/i32-icmp.ll
index 04b1eeaad21a..34557696cc57 100644
--- a/llvm/test/CodeGen/RISCV/i32-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/i32-icmp.ll
@@ -19,7 +19,7 @@ define i32 @icmp_eq(i32 %a, i32 %b) nounwind {
 define i32 @icmp_eq_constant(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_eq_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    xori a0, a0, 42
+; RV32I-NEXT:    addi a0, a0, -42
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
   %1 = icmp eq i32 %a, 42
@@ -27,6 +27,40 @@ define i32 @icmp_eq_constant(i32 %a) nounwind {
   ret i32 %2
 }
 
+define i32 @icmp_eq_constant_2048(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant_2048:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi a0, a0, -2048
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp eq i32 %a, 2048
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @icmp_eq_constant_neg_2048(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant_neg_2048:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi a1, zero, -2048
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp eq i32 %a, -2048
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @icmp_eq_constant_neg_2047(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant_neg_2047:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi a0, a0, 2047
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp eq i32 %a, -2047
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_eqz(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_eqz:
 ; RV32I:       # %bb.0:
@@ -51,7 +85,7 @@ define i32 @icmp_ne(i32 %a, i32 %b) nounwind {
 define i32 @icmp_ne_constant(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_ne_constant:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    xori a0, a0, 42
+; RV32I-NEXT:    addi a0, a0, -42
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
   %1 = icmp ne i32 %a, 42
@@ -59,6 +93,29 @@ define i32 @icmp_ne_constant(i32 %a) nounwind {
   ret i32 %2
 }
 
+define i32 @icmp_ne_constant_2048(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ne_constant_2048:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi a0, a0, -2048
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp ne i32 %a, 2048
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @icmp_ne_constant_neg_2048(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ne_constant_neg_2048:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi a1, zero, -2048
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+  %1 = icmp ne i32 %a, -2048
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_nez(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_nez:
 ; RV32I:       # %bb.0:

diff  --git a/llvm/test/CodeGen/RISCV/setcc-logic.ll b/llvm/test/CodeGen/RISCV/setcc-logic.ll
index 0c29bf505234..dfaee187db9c 100644
--- a/llvm/test/CodeGen/RISCV/setcc-logic.ll
+++ b/llvm/test/CodeGen/RISCV/setcc-logic.ll
@@ -102,9 +102,9 @@ define i1 @and_icmps_const_1bit_
diff (i32 %x) nounwind {
 define i1 @and_icmps_const_not1bit_
diff (i32 %x) nounwind {
 ; RV32I-LABEL: and_icmps_const_not1bit_
diff :
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    xori a1, a0, 44
+; RV32I-NEXT:    addi a1, a0, -44
 ; RV32I-NEXT:    snez a1, a1
-; RV32I-NEXT:    xori a0, a0, 92
+; RV32I-NEXT:    addi a0, a0, -92
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    and a0, a1, a0
 ; RV32I-NEXT:    ret
@@ -113,9 +113,9 @@ define i1 @and_icmps_const_not1bit_
diff (i32 %x) nounwind {
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    slli a0, a0, 32
 ; RV64I-NEXT:    srli a0, a0, 32
-; RV64I-NEXT:    xori a1, a0, 44
+; RV64I-NEXT:    addi a1, a0, -44
 ; RV64I-NEXT:    snez a1, a1
-; RV64I-NEXT:    xori a0, a0, 92
+; RV64I-NEXT:    addi a0, a0, -92
 ; RV64I-NEXT:    snez a0, a0
 ; RV64I-NEXT:    and a0, a1, a0
 ; RV64I-NEXT:    ret


        


More information about the llvm-commits mailing list