[llvm] [AMDGPU] Select v_bfe_u32 for i8/i16 (and (srl x, c), mask) (PR #182446)

Vigneshwar Jayakumar via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 3 10:01:58 PST 2026


================
@@ -4157,17 +4157,32 @@ def IMMZeroBasedBitfieldMask : ImmLeaf <i32, [{
   return isMask_32(Imm);
 }]>;
 
+def IMMZeroBasedBitfieldMask16 : ImmLeaf <i16, [{
+  return isUInt<16>(Imm) && isMask_32(Imm);
+}]>;
+
 def IMMPopCount : SDNodeXForm<imm, [{
   return CurDAG->getTargetConstant(llvm::popcount(N->getZExtValue()), SDLoc(N),
                                    MVT::i32);
 }]>;
 
+def IMMAsI32 : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i32);
+}]>;
+
 def : AMDGPUPat <
   (DivergentBinFrag<and> (i32 (srl i32:$src, i32:$rshift)),
                          IMMZeroBasedBitfieldMask:$mask),
   (V_BFE_U32_e64 $src, $rshift, (i32 (IMMPopCount $mask)))
 >;
 
+let True16Predicate = NotUseRealTrue16Insts in
+def : AMDGPUPat <
+  (i16 (DivergentBinFrag<and> (srl_oneuse i16:$src, (i16 imm:$rshift)),
+                              IMMZeroBasedBitfieldMask16:$mask)),
+  (V_BFE_U32_e64 $src, (i32 (IMMAsI32 $rshift)), (i32 (IMMPopCount $mask)))
----------------
VigneshwarJ wrote:

Yes, I agree. But the existing i32's bfe_32 selection pattern is already using popcount. And popcount won't be semantically wrong here because isMask_32 (IMMZeroBasedBitfieldMask/16) guarantees the immediate is a contiguous mask of ones starting from bit 0. But if you want me to create a new pattern to check counttrailingones, I can.

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


More information about the llvm-commits mailing list