From cdf09ce7e774524765b832d714a7fca77b154b44 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 28 Dec 2022 13:08:28 -0800 Subject: [PATCH] [RISCV] Support SRLI in hasAllNBitUsers. We can recursively look through SRLI if the shift amount is less than the demanded bits. We can reduce the demanded bit count by the shift amount and check the users of the SRLI. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 9 +++++++++ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 12 ++++++++++++ llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll | 14 +++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 2fb348e..e80200b 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2375,6 +2375,15 @@ bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits, if (!hasAllNBitUsers(User, Bits, Depth + 1)) return false; break; + case RISCV::SRLI: { + unsigned ShAmt = User->getConstantOperandVal(1); + // If we are shifting right by less than Bits, and users don't demand any + // bits that were shifted into [Bits-1:0], then we can consider this as an + // N-Bit user. + if (Bits > ShAmt && hasAllNBitUsers(User, Bits - ShAmt, Depth + 1)) + break; + return false; + } case RISCV::SEXT_B: case RISCV::PACKH: if (Bits < 8) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 5f705f2..742fee0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2572,6 +2572,18 @@ bool RISCVInstrInfo::hasAllNBitUsers(const MachineInstr &OrigMI, break; return false; + case RISCV::SRLI: { + // If we are shifting right by less than Bits, and users don't demand + // any bits that were shifted into [Bits-1:0], then we can consider this + // as an N-Bit user. + unsigned ShAmt = UserMI->getOperand(2).getImm(); + if (Bits > ShAmt) { + Worklist.push_back(std::make_pair(UserMI, Bits - ShAmt)); + break; + } + return false; + } + // these overwrite higher input bits, otherwise the lower word of output // depends only on the lower word of input. So check their uses read W. case RISCV::SLLI: diff --git a/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll index bbba483..3e73f28 100644 --- a/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll +++ b/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll @@ -54,12 +54,12 @@ define i8 @test_cttz_i8(i8 %a) nounwind { ; RV64NOZBB-NEXT: andi a1, a0, 255 ; RV64NOZBB-NEXT: beqz a1, .LBB0_2 ; RV64NOZBB-NEXT: # %bb.1: # %cond.false -; RV64NOZBB-NEXT: addi a1, a0, -1 +; RV64NOZBB-NEXT: addiw a1, a0, -1 ; RV64NOZBB-NEXT: not a0, a0 ; RV64NOZBB-NEXT: and a0, a0, a1 ; RV64NOZBB-NEXT: srli a1, a0, 1 ; RV64NOZBB-NEXT: andi a1, a1, 85 -; RV64NOZBB-NEXT: sub a0, a0, a1 +; RV64NOZBB-NEXT: subw a0, a0, a1 ; RV64NOZBB-NEXT: andi a1, a0, 51 ; RV64NOZBB-NEXT: srli a0, a0, 2 ; RV64NOZBB-NEXT: andi a0, a0, 51 @@ -434,12 +434,12 @@ define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind { ; ; RV64NOZBB-LABEL: test_cttz_i8_zero_undef: ; RV64NOZBB: # %bb.0: -; RV64NOZBB-NEXT: addi a1, a0, -1 +; RV64NOZBB-NEXT: addiw a1, a0, -1 ; RV64NOZBB-NEXT: not a0, a0 ; RV64NOZBB-NEXT: and a0, a0, a1 ; RV64NOZBB-NEXT: srli a1, a0, 1 ; RV64NOZBB-NEXT: andi a1, a1, 85 -; RV64NOZBB-NEXT: sub a0, a0, a1 +; RV64NOZBB-NEXT: subw a0, a0, a1 ; RV64NOZBB-NEXT: andi a1, a0, 51 ; RV64NOZBB-NEXT: srli a0, a0, 2 ; RV64NOZBB-NEXT: andi a0, a0, 51 @@ -777,7 +777,7 @@ define i8 @test_ctlz_i8(i8 %a) nounwind { ; RV64NOZBB-NEXT: not a0, a0 ; RV64NOZBB-NEXT: srli a1, a0, 1 ; RV64NOZBB-NEXT: andi a1, a1, 85 -; RV64NOZBB-NEXT: sub a0, a0, a1 +; RV64NOZBB-NEXT: subw a0, a0, a1 ; RV64NOZBB-NEXT: andi a1, a0, 51 ; RV64NOZBB-NEXT: srli a0, a0, 2 ; RV64NOZBB-NEXT: andi a0, a0, 51 @@ -1391,7 +1391,7 @@ define i8 @test_ctlz_i8_zero_undef(i8 %a) nounwind { ; RV64NOZBB-NEXT: not a0, a0 ; RV64NOZBB-NEXT: srli a1, a0, 1 ; RV64NOZBB-NEXT: andi a1, a1, 85 -; RV64NOZBB-NEXT: sub a0, a0, a1 +; RV64NOZBB-NEXT: subw a0, a0, a1 ; RV64NOZBB-NEXT: andi a1, a0, 51 ; RV64NOZBB-NEXT: srli a0, a0, 2 ; RV64NOZBB-NEXT: andi a0, a0, 51 @@ -1938,7 +1938,7 @@ define i8 @test_ctpop_i8(i8 %a) nounwind { ; RV64NOZBB: # %bb.0: ; RV64NOZBB-NEXT: srli a1, a0, 1 ; RV64NOZBB-NEXT: andi a1, a1, 85 -; RV64NOZBB-NEXT: sub a0, a0, a1 +; RV64NOZBB-NEXT: subw a0, a0, a1 ; RV64NOZBB-NEXT: andi a1, a0, 51 ; RV64NOZBB-NEXT: srli a0, a0, 2 ; RV64NOZBB-NEXT: andi a0, a0, 51 -- 2.7.4