[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