[llvm] AMDGPU/GlobalISel: RegBankLegalize rules for s_bitreplicate (PR #189138)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 03:50:12 PDT 2026


================
@@ -924,6 +890,80 @@ bool RegBankLegalizeHelper::lowerSplitBitCount64To32(MachineInstr &MI) {
   return true;
 }
 
+bool RegBankLegalizeHelper::lowerBitReplicateToVALU(MachineInstr &MI) {
+  // Lower divergent s_bitreplicate (bit i -> bits 2i, 2i+1) to VALU by
+  // splitting into two 16-bit halves and spreading bits via:
+  //   lo = v_perm_b32(0, src, 0x0C010C00)   // [00][B1][00][B0]
+  //   hi = v_perm_b32(0, src, 0x0C030C02)   // [00][B3][00][B2]
+  //   M4 = (x | (x << 4)) & 0x0F0F0F0F      // 4-bit spread
+  //   M2 = (M4 | (M4 << 2)) & 0x33333333    // 2-bit spread
+  //   M1 = (M2 | (M2 << 1)) & 0x55555555    // 1-bit spread
+  //   R  = M1 | (M1 << 1)                   // duplicate each bit
+  Register Dst = MI.getOperand(0).getReg();
+  Register Src = MI.getOperand(2).getReg();
+
+  // v_perm_b32 splits the input into 16-bit halves and spreads each half's
+  // bytes with zero-byte gaps in one instruction. Selector byte values:
+  // 0x00-0x03 = src byte N, 0x0C = zero byte
+  // e.g. 0x134C3A92 -> Hi: [0013][004C], Lo: [003A][0092]
+  auto Zero = B.buildConstant(VgprRB_S32, 0);
+  Register LoByteSpread =
+      B.buildIntrinsic(Intrinsic::amdgcn_perm, {VgprRB_S32})
----------------
arsenm wrote:

perm is not a universally available intrinsic 

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


More information about the llvm-commits mailing list