[llvm] [AMDGPU] Compute GISel KnownBits for S_BFE instructions (PR #141588)

Pierre van Houtryve via llvm-commits llvm-commits at lists.llvm.org
Tue May 27 05:43:17 PDT 2025


https://github.com/Pierre-vh created https://github.com/llvm/llvm-project/pull/141588

None

>From 0793c9530921fd8050950f569947f25b405d1774 Mon Sep 17 00:00:00 2001
From: pvanhout <pierre.vanhoutryve at amd.com>
Date: Tue, 27 May 2025 10:26:24 +0200
Subject: [PATCH] [AMDGPU] Compute GISel KnownBits for S_BFE instructions

---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 45 +++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index ade88a16193b8..1a1490b55d3e4 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -16502,12 +16502,57 @@ static void knownBitsForWorkitemID(const GCNSubtarget &ST,
   Known.Zero.setHighBits(llvm::countl_zero(MaxValue));
 }
 
+static void knownBitsForSBFE(const MachineInstr &MI, GISelValueTracking &VT,
+                             KnownBits &Known, const APInt &DemandedElts,
+                             unsigned BFEWidth, bool SExt) {
+  const MachineRegisterInfo &MRI = VT.getMachineFunction().getRegInfo();
+  const MachineOperand &Src1 = MI.getOperand(2);
+
+  unsigned Src1Cst = 0;
+  if (Src1.isImm())
+    Src1Cst = Src1.getImm();
+  else if (Src1.isReg()) {
+    auto Cst = getIConstantVRegValWithLookThrough(Src1.getReg(), MRI);
+    if (!Cst)
+      return;
+    Src1Cst = Cst->Value.getZExtValue();
+  } else
+    return;
+
+  const unsigned Mask = maskTrailingOnes<unsigned>(6);
+  const unsigned Offset = Src1Cst & Mask;
+  const unsigned Width = (Src1Cst >> 16) & Mask;
+
+  VT.computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts);
+
+  const uint64_t WidthMask = maskTrailingOnes<uint64_t>(Width);
+  Known.Zero = Known.Zero.shl(Offset) & WidthMask;
+  Known.One = Known.One.shl(Offset) & WidthMask;
+
+  if (SExt)
+    Known.sextInReg(Width);
+  else
+    Known.Zero |= maskLeadingOnes<unsigned>(BFEWidth - Width);
+}
+
 void SITargetLowering::computeKnownBitsForTargetInstr(
     GISelValueTracking &VT, Register R, KnownBits &Known,
     const APInt &DemandedElts, const MachineRegisterInfo &MRI,
     unsigned Depth) const {
   const MachineInstr *MI = MRI.getVRegDef(R);
   switch (MI->getOpcode()) {
+  case AMDGPU::S_BFE_I32:
+    return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/32,
+                            /*SExt=*/true);
+  case AMDGPU::S_BFE_U32:
+    return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/32,
+                            /*SExt=*/false);
+  case AMDGPU::S_BFE_I64:
+    return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/64,
+                            /*SExt=*/true);
+  case AMDGPU::S_BFE_U64:
+    return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/64,
+                            /*SExt=*/false);
   case AMDGPU::G_INTRINSIC:
   case AMDGPU::G_INTRINSIC_CONVERGENT: {
     Intrinsic::ID IID = cast<GIntrinsic>(MI)->getIntrinsicID();



More information about the llvm-commits mailing list