1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
Andrew Wei 2020-02-11 22:42:45 +08:00
parent 148155b981
commit a353ef73cc
3 changed files with 87 additions and 10 deletions

View File

@ -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)>;

View File

@ -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:

View File

@ -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