diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -10309,6 +10309,21 @@ DAG.getConstant(~1, DL, MVT::i64), N0.getOperand(1)); } + // Fold (xor (setcc constant, y, setlt), 1) -> (setcc y, constant + 1, setlt) + if (N0.getOpcode() == ISD::SETCC && isOneConstant(N1)) { + EVT VT = N0.getValueType(); + SDLoc DL(N0); + SDValue N00 = N0.getOperand(0); + SDValue N01 = N0.getOperand(1); + auto *ConstN00 = dyn_cast(N00); + ISD::CondCode CC = cast(N0.getOperand(2))->get(); + if (ConstN00 && CC == ISD::SETLT) { + int64_t Imm = ConstN00->getSExtValue(); + if (isInt<12>(Imm + 1)) + return DAG.getSetCC(DL, VT, N01, DAG.getConstant(Imm + 1, DL, VT), CC); + } + } + if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget)) return V; // fold (xor (select cond, 0, y), x) -> diff --git a/llvm/test/CodeGen/RISCV/double-select-icmp.ll b/llvm/test/CodeGen/RISCV/double-select-icmp.ll --- a/llvm/test/CodeGen/RISCV/double-select-icmp.ll +++ b/llvm/test/CodeGen/RISCV/double-select-icmp.ll @@ -482,8 +482,7 @@ define double @select_icmp_sgt_zero(i32 signext %a) { ; CHECK-LABEL: select_icmp_sgt_zero: ; CHECK: # %bb.0: -; CHECK-NEXT: sgtz a0, a0 -; CHECK-NEXT: xori a0, a0, 1 +; CHECK-NEXT: slti a0, a0, 1 ; CHECK-NEXT: fcvt.d.w fa0, a0 ; CHECK-NEXT: ret ; @@ -491,8 +490,7 @@ ; RV32ZDINX: # %bb.0: ; RV32ZDINX-NEXT: addi sp, sp, -16 ; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sgtz a0, a0 -; RV32ZDINX-NEXT: xori a0, a0, 1 +; RV32ZDINX-NEXT: slti a0, a0, 1 ; RV32ZDINX-NEXT: fcvt.d.w a0, a0 ; RV32ZDINX-NEXT: sw a0, 8(sp) ; RV32ZDINX-NEXT: sw a1, 12(sp) @@ -503,8 +501,7 @@ ; ; RV64ZDINX-LABEL: select_icmp_sgt_zero: ; RV64ZDINX: # %bb.0: -; RV64ZDINX-NEXT: sgtz a0, a0 -; RV64ZDINX-NEXT: xori a0, a0, 1 +; RV64ZDINX-NEXT: slti a0, a0, 1 ; RV64ZDINX-NEXT: fcvt.d.w a0, a0 ; RV64ZDINX-NEXT: ret %1 = icmp sgt i32 %a, 0 diff --git a/llvm/test/CodeGen/RISCV/float-select-icmp.ll b/llvm/test/CodeGen/RISCV/float-select-icmp.ll --- a/llvm/test/CodeGen/RISCV/float-select-icmp.ll +++ b/llvm/test/CodeGen/RISCV/float-select-icmp.ll @@ -248,15 +248,13 @@ define float @select_icmp_sgt_zero(i32 signext %a) { ; CHECK-LABEL: select_icmp_sgt_zero: ; CHECK: # %bb.0: -; CHECK-NEXT: sgtz a0, a0 -; CHECK-NEXT: xori a0, a0, 1 +; CHECK-NEXT: slti a0, a0, 1 ; CHECK-NEXT: fcvt.s.w fa0, a0 ; CHECK-NEXT: ret ; ; CHECKZFINX-LABEL: select_icmp_sgt_zero: ; CHECKZFINX: # %bb.0: -; CHECKZFINX-NEXT: sgtz a0, a0 -; CHECKZFINX-NEXT: xori a0, a0, 1 +; CHECKZFINX-NEXT: slti a0, a0, 1 ; CHECKZFINX-NEXT: fcvt.s.w a0, a0 ; CHECKZFINX-NEXT: ret %1 = icmp sgt i32 %a, 0 diff --git a/llvm/test/CodeGen/RISCV/half-select-icmp.ll b/llvm/test/CodeGen/RISCV/half-select-icmp.ll --- a/llvm/test/CodeGen/RISCV/half-select-icmp.ll +++ b/llvm/test/CodeGen/RISCV/half-select-icmp.ll @@ -510,30 +510,26 @@ define half @select_icmp_sgt_zero(i32 signext %a) { ; CHECK-LABEL: select_icmp_sgt_zero: ; CHECK: # %bb.0: -; CHECK-NEXT: sgtz a0, a0 -; CHECK-NEXT: xori a0, a0, 1 +; CHECK-NEXT: slti a0, a0, 1 ; CHECK-NEXT: fcvt.h.w fa0, a0 ; CHECK-NEXT: ret ; ; CHECKIZHINX-LABEL: select_icmp_sgt_zero: ; CHECKIZHINX: # %bb.0: -; CHECKIZHINX-NEXT: sgtz a0, a0 -; CHECKIZHINX-NEXT: xori a0, a0, 1 +; CHECKIZHINX-NEXT: slti a0, a0, 1 ; CHECKIZHINX-NEXT: fcvt.h.w a0, a0 ; CHECKIZHINX-NEXT: ret ; ; CHECKIZFHMIN-LABEL: select_icmp_sgt_zero: ; CHECKIZFHMIN: # %bb.0: -; CHECKIZFHMIN-NEXT: sgtz a0, a0 -; CHECKIZFHMIN-NEXT: xori a0, a0, 1 +; CHECKIZFHMIN-NEXT: slti a0, a0, 1 ; CHECKIZFHMIN-NEXT: fcvt.s.w fa5, a0 ; CHECKIZFHMIN-NEXT: fcvt.h.s fa0, fa5 ; CHECKIZFHMIN-NEXT: ret ; ; CHECKIZHINXMIN-LABEL: select_icmp_sgt_zero: ; CHECKIZHINXMIN: # %bb.0: -; CHECKIZHINXMIN-NEXT: sgtz a0, a0 -; CHECKIZHINXMIN-NEXT: xori a0, a0, 1 +; CHECKIZHINXMIN-NEXT: slti a0, a0, 1 ; CHECKIZHINXMIN-NEXT: fcvt.s.w a0, a0 ; CHECKIZHINXMIN-NEXT: fcvt.h.s a0, a0 ; CHECKIZHINXMIN-NEXT: ret