[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