[llvm] [RISCV] Porting hasAllNBitUsers to RISCV GISel for instruction select (PR #124678)

Luke Quinn via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 02:57:56 PST 2025


================
@@ -186,6 +199,169 @@ RISCVInstructionSelector::RISCVInstructionSelector(
 {
 }
 
+bool RISCVInstructionSelector::hasAllNBitUsers(const MachineInstr &MI,
+                                               unsigned Bits,
+                                               const unsigned Depth) const {
+
+  assert((MI.getOpcode() == TargetOpcode::G_ADD ||
+          MI.getOpcode() == TargetOpcode::G_SUB ||
+          MI.getOpcode() == TargetOpcode::G_MUL ||
+          MI.getOpcode() == TargetOpcode::G_SHL ||
+          MI.getOpcode() == TargetOpcode::G_LSHR ||
+          MI.getOpcode() == TargetOpcode::G_AND ||
+          MI.getOpcode() == TargetOpcode::G_OR ||
+          MI.getOpcode() == TargetOpcode::G_XOR ||
+          MI.getOpcode() == TargetOpcode::G_SEXT_INREG || Depth != 0) &&
+         "Unexpected opcode");
+
+  if (Depth >= /*TODO*/ 20)
+    return false;
+
+  // Skip Vectors
+  // if(Depth == 0 && !MI.getOperand(0).isScalar())
+  //    return false;
+
+  for (MachineInstr &Use : MRI->use_instructions(MI.getOperand(0).getReg())) {
+
+    switch (Use.getOpcode()) {
+    default:
+      // if (vectorPseudoHasAllNBitUsers(User, Use.getNumOperands(), Bits, TII))
+      //   break;
+      return false;
+    case RISCV::ADDW:
+    case RISCV::ADDIW:
+    case RISCV::SUBW:
+    case RISCV::MULW:
+    case RISCV::SLLW:
+    case RISCV::SLLIW:
+    case RISCV::SRAW:
+    case RISCV::SRAIW:
+    case RISCV::SRLW:
+    case RISCV::SRLIW:
+    case RISCV::DIVW:
+    case RISCV::DIVUW:
+    case RISCV::REMW:
+    case RISCV::REMUW:
+    case RISCV::ROLW:
+    case RISCV::RORW:
+    case RISCV::RORIW:
+    case RISCV::CLZW:
+    case RISCV::CTZW:
+    case RISCV::CPOPW:
+    case RISCV::SLLI_UW:
+    case RISCV::FMV_W_X:
+    case RISCV::FCVT_H_W:
+    case RISCV::FCVT_H_W_INX:
+    case RISCV::FCVT_H_WU:
+    case RISCV::FCVT_H_WU_INX:
+    case RISCV::FCVT_S_W:
+    case RISCV::FCVT_S_W_INX:
+    case RISCV::FCVT_S_WU:
+    case RISCV::FCVT_S_WU_INX:
+    case RISCV::FCVT_D_W:
+    case RISCV::FCVT_D_W_INX:
+    case RISCV::FCVT_D_WU:
+    case RISCV::FCVT_D_WU_INX:
+    case RISCV::TH_REVW:
+    case RISCV::TH_SRRIW:
+      if (Bits >= 32)
+        break;
+      return false;
+    case RISCV::SLL:
+    case RISCV::SRA:
+    case RISCV::SRL:
+    case RISCV::ROL:
+    case RISCV::ROR:
+    case RISCV::BSET:
+    case RISCV::BCLR:
+    case RISCV::BINV:
+      // Shift amount operands only use log2(Xlen) bits.
+      if (Use.getNumOperands() == 1 && Bits >= Log2_32(Subtarget->getXLen()))
+        break;
+      return false;
+    case RISCV::SLLI:
+      // SLLI only uses the lower (XLen - ShAmt) bits.
+      if (Bits >= Subtarget->getXLen() - Use.getOperand(2).getImm())
+        break;
+      return false;
+    case RISCV::ANDI:
+      if (Bits >= (unsigned)llvm::bit_width<uint64_t>(
+                      ~((uint64_t)Use.getOperand(2).getImm())))
----------------
lquinn2015 wrote:

The is a issue i will fix it. I think I was confusing ORI and ANDI from the RISCVOptWInstrs. But I think i am also confused because ANDI could only 12 bits so I was thinking the ConstantValue Types way of calculating bits width would return 12 bits but I don't believe that was a correct interpretation. 

The above definitely doesn't work for positive numbers though so it is clearly not correct :/

https://github.com/llvm/llvm-project/pull/124678


More information about the llvm-commits mailing list