diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -351,6 +351,10 @@ def simm12_plus1 : ImmLeaf(Imm) && Imm != -2048) || Imm == 2048;}]>; +// A 12-bit signed immediate sub one where the imm range will be -2049~2046. +def simm12_sub1 : ImmLeaf(Imm) && Imm != 2047) || Imm == -2049;}]>; + // A 6-bit constant greater than 32. def uimm6gt32 : ImmLeaf(Imm) && Imm > 32; @@ -373,9 +377,9 @@ N->getValueType(0)); }]>; -// Return an immediate value plus 32. -def ImmPlus32 : SDNodeXFormgetTargetConstant(N->getSExtValue() + 32, SDLoc(N), +// Return an immediate value plus 1. +def ImmPlus1 : SDNodeXFormgetTargetConstant(N->getSExtValue() + 1, SDLoc(N), N->getValueType(0)); }]>; @@ -1209,6 +1213,11 @@ def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>; def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>; +let Predicates = [IsRV32] in { +def : Pat<(setgt GPR:$rs1, simm12_sub1:$imm), + (XORI (SLTI GPR:$rs1, (ImmPlus1 simm12_sub1:$imm)), 1)>; +} + def IntCCtoRISCVCC : SDNodeXForm(N->getOperand(2))->get(); RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC); diff --git a/llvm/test/CodeGen/RISCV/i32-icmp.ll b/llvm/test/CodeGen/RISCV/i32-icmp.ll --- a/llvm/test/CodeGen/RISCV/i32-icmp.ll +++ b/llvm/test/CodeGen/RISCV/i32-icmp.ll @@ -178,6 +178,62 @@ ret i32 %2 } +define i32 @icmp_sgt_constant(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: icmp_sgt_constant: +; RV32I: # %bb.0: +; RV32I-NEXT: slti a0, a0, 6 +; RV32I-NEXT: xori a0, a0, 1 +; RV32I-NEXT: ret + %1 = icmp sgt i32 %a, 5 + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @icmp_sgt_constant_2046(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: icmp_sgt_constant_2046: +; RV32I: # %bb.0: +; RV32I-NEXT: slti a0, a0, 2047 +; RV32I-NEXT: xori a0, a0, 1 +; RV32I-NEXT: ret + %1 = icmp sgt i32 %a, 2046 + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @icmp_sgt_constant_2047(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: icmp_sgt_constant_2047: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 2047 +; RV32I-NEXT: slt a0, a1, a0 +; RV32I-NEXT: ret + %1 = icmp sgt i32 %a, 2047 + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @icmp_sgt_constant_neg_2049(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: icmp_sgt_constant_neg_2049: +; RV32I: # %bb.0: +; RV32I-NEXT: slti a0, a0, -2048 +; RV32I-NEXT: xori a0, a0, 1 +; RV32I-NEXT: ret + %1 = icmp sgt i32 %a, -2049 + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @icmp_sgt_constant_neg_2050(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: icmp_sgt_constant_neg_2050: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 1048575 +; RV32I-NEXT: addi a1, a1, 2046 +; RV32I-NEXT: slt a0, a1, a0 +; RV32I-NEXT: ret + %1 = icmp sgt i32 %a, -2050 + %2 = zext i1 %1 to i32 + ret i32 %2 +} + define i32 @icmp_sge(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: icmp_sge: ; RV32I: # %bb.0: