From 12fee611ca533231f12c0b6518bfc525c893f238 Mon Sep 17 00:00:00 2001 From: LiaoChunyu Date: Sat, 17 Jun 2023 09:33:48 +0800 Subject: [PATCH] [RISCV] Fold special case (xor (setcc constant, y, setlt), 1) -> (setcc y, constant + 1, setlt) Improve D151719. (xor (setcc constant, y, setlt), 1) -> (setcc y, constant + 1, setlt) https://alive2.llvm.org/ce/z/BZNEia Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D152128 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 14 ++++++++++++++ llvm/test/CodeGen/RISCV/double-select-icmp.ll | 9 +++------ llvm/test/CodeGen/RISCV/float-select-icmp.ll | 6 ++---- llvm/test/CodeGen/RISCV/half-select-icmp.ll | 12 ++++-------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index d7b841c..46e94e2 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -10474,6 +10474,20 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, DAG.getConstant(~1, DL, MVT::i64), N0.getOperand(1)); } + // Fold (xor (setcc constant, y, setlt), 1) -> (setcc y, constant + 1, setlt) + if (N0.hasOneUse() && N0.getOpcode() == ISD::SETCC && isOneConstant(N1)) { + auto *ConstN00 = dyn_cast(N0.getOperand(0)); + ISD::CondCode CC = cast(N0.getOperand(2))->get(); + if (ConstN00 && CC == ISD::SETLT) { + EVT VT = N0.getValueType(); + SDLoc DL(N0); + const APInt &Imm = ConstN00->getAPIntValue(); + if ((Imm + 1).isSignedIntN(12)) + return DAG.getSetCC(DL, VT, N0.getOperand(1), + 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 index 9fdab5f..cd28b58 100644 --- 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_slt_one(i32 signext %a) { 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 @@ define double @select_icmp_sgt_zero(i32 signext %a) { ; 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 @@ define double @select_icmp_sgt_zero(i32 signext %a) { ; ; 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 index 1d2aeaa..e8f420f 100644 --- 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_slt_one(i32 signext %a) { 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 index 465579a..a2da15e 100644 --- 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_slt_one(i32 signext %a) { 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 -- 2.7.4