[llvm] [AMDGPU] Select the high-half 16-bit packing idiom to v_lshl_or_b32 (PR #206058)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 03:21:45 PDT 2026


================
@@ -4024,6 +4024,28 @@ def : GCNPat <
   (v2i16 (V_LSHL_OR_B32_e64 $src1, (i32 16), (i32 (V_AND_B32_e64 (i32 (V_MOV_B32_e32 (i32 0xffff))), $src0))))
 >;
 
+// Fold the (hi << 16) | z high-half packing idiom into v_lshl_or_b32.
+// DAGCombine canonicalizes a 16-bit value shifted into the high half to
+// bitcast(build_vector (i16 0), hi), leaving no shl for the
+// (or (shl x, y), z) selection to match, so match the build_vector directly.
+let True16Predicate = NotUseRealTrue16Insts in
+def : GCNPat <
+  (i32 (DivergentBinFrag<or>
+    (i32 (bitconvert (v2i16 (build_vector (i16 0), (i16 VGPR_32:$src_hi))))),
+    i32:$src2)),
+  (V_LSHL_OR_B32_e64 VGPR_32:$src_hi, (i32 16), VSrc_b32:$src2)
+>;
+
+let True16Predicate = UseRealTrue16Insts in
+def : GCNPat <
+  (i32 (DivergentBinFrag<or>
+    (i32 (bitconvert (v2i16 (build_vector (i16 0), (i16 VGPR_16:$src_hi))))),
+    i32:$src2)),
+  (V_LSHL_OR_B32_e64
+    (i32 (REG_SEQUENCE VGPR_32, VGPR_16:$src_hi, lo16, (i16 (IMPLICIT_DEF)), hi16)),
+    (i32 16), VSrc_b32:$src2)
----------------
jayfoad wrote:

To explain a bit more: the problem with this pattern is that it forces $src_hi into the low half of a VGPR. In true16 mode we'd like to let $src_hi live wherever it wants (low or high half of any VGPR) and generate different code sequences accordingly.

However, this is a pre-existing problem. We have other true16 patterns that do similar things, forcing either their inputs or output to go in the low or high half of a VGPR. Until we have a better way to fix that general problem, this PR seems fine.

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


More information about the llvm-commits mailing list