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:
parent
148155b981
commit
a353ef73cc
@ -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)>;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user