[clang] [llvm] [X86] AVX10_V2_AUX Implementation (PR #206888)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 30 08:15:20 PDT 2026


================
@@ -0,0 +1,564 @@
+//===-- X86InstrAVX10_V2_AUX.td - AVX10 V2 AUX Instructions --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the X86 AVX10 V2 AUX instruction set, defining the
+// instructions and their encoding.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// AVX10 V2 AUX Multiclass Definitions
+//===----------------------------------------------------------------------===//
+
+// Group A multiclass: PS(f32) -> i8 truncating conversion (quarter-size output)
+// Output is always xmm for all VL variants.
+// Adapts avx512_vcvt_fp for each VL level with explicit dest/src type mappings.
+multiclass avx10_v2aux_cvt_trunc_ps2i8<bits<8> opc, string OpcodeStr,
+                                        SDPatternOperator OpNode,
+                                        SDPatternOperator MaskOpNode> {
+  let ExeDomain = SSEPackedSingle in {
+    let Uses = []<Register>, mayRaiseFPException = 0 in {
+      defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i8x_info, v16f32_info,
+                              OpNode, OpNode, WriteCvtPH2PSZ>, EVEX_V512;
+      // Z256/Z128: use null_frag because element count mismatch between
+      // dest (v16i8) and source (v8f32/v4f32) prevents avx512_vcvt_fp from
+      // generating correct masked patterns. Explicit Pat patterns below.
+      defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v16i8x_info, v8f32x_info,
+                                 null_frag, null_frag,
+                                 WriteCvtPH2PSZ, v8f32x_info.BroadcastStr,
+                                 "{y}", v8f32x_info.MemOp,
+                                 v8f32x_info.KRCWM>, EVEX_V256;
+      defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v16i8x_info, v4f32x_info,
+                                 null_frag, null_frag,
+                                 WriteCvtPH2PSZ, v4f32x_info.BroadcastStr,
+                                 "{x}", f128mem,
+                                 v4f32x_info.KRCWM>, EVEX_V128;
+    }
+  }
+
+  // InstAliases for x/y suffixes
+  def : InstAlias<OpcodeStr#"x\t{$src, $dst|$dst, $src}",
+                  (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst,
+                  VR128X:$src), 0>;
+  def : InstAlias<OpcodeStr#"x\t{$src, $dst|$dst, $src}",
+                  (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst,
+                  f128mem:$src), 0, "intel">;
+  def : InstAlias<OpcodeStr#"y\t{$src, $dst|$dst, $src}",
+                  (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst,
+                  VR256X:$src), 0>;
+  def : InstAlias<OpcodeStr#"y\t{$src, $dst|$dst, $src}",
+                  (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst,
+                  f256mem:$src), 0, "intel">;
+
+  // Explicit patterns for Z256 (8 source elements, VK8WM mask)
+  // Unmasked
+  def : Pat<(v16i8 (OpNode (v8f32 VR256X:$src))),
+            (!cast<Instruction>(NAME # "Z256rr") VR256X:$src)>;
+  // Masked (merge)
+  def : Pat<(MaskOpNode (v8f32 VR256X:$src), (v16i8 VR128X:$src0),
+                         VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rrk") VR128X:$src0, VK8WM:$mask,
+                                VR256X:$src)>;
+  // Masked (zero)
+  def : Pat<(MaskOpNode (v8f32 VR256X:$src), v16i8x_info.ImmAllZerosV,
+                         VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rrkz") VK8WM:$mask,
+                                VR256X:$src)>;
+  // Memory
+  def : Pat<(v16i8 (OpNode (loadv8f32 addr:$src))),
+            (!cast<Instruction>(NAME # "Z256rm") addr:$src)>;
+  def : Pat<(MaskOpNode (loadv8f32 addr:$src), (v16i8 VR128X:$src0),
+                         VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmk") VR128X:$src0, VK8WM:$mask,
+                                addr:$src)>;
+  def : Pat<(MaskOpNode (loadv8f32 addr:$src), v16i8x_info.ImmAllZerosV,
+                         VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmkz") VK8WM:$mask, addr:$src)>;
+  // Broadcast
+  def : Pat<(v16i8 (OpNode (v8f32 (X86VBroadcastld32 addr:$src)))),
+            (!cast<Instruction>(NAME # "Z256rmb") addr:$src)>;
+  def : Pat<(MaskOpNode (v8f32 (X86VBroadcastld32 addr:$src)),
+                          (v16i8 VR128X:$src0), VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmbk") VR128X:$src0, VK8WM:$mask,
+                                addr:$src)>;
+  def : Pat<(MaskOpNode (v8f32 (X86VBroadcastld32 addr:$src)),
+                          v16i8x_info.ImmAllZerosV, VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmbkz") VK8WM:$mask, addr:$src)>;
+
+  // Explicit patterns for Z128 (4 source elements, VK4WM mask)
+  // Unmasked
+  def : Pat<(v16i8 (OpNode (v4f32 VR128X:$src))),
+            (!cast<Instruction>(NAME # "Z128rr") VR128X:$src)>;
+  // Masked (merge)
+  def : Pat<(MaskOpNode (v4f32 VR128X:$src), (v16i8 VR128X:$src0),
+                         VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rrk") VR128X:$src0, VK4WM:$mask,
+                                VR128X:$src)>;
+  // Masked (zero)
+  def : Pat<(MaskOpNode (v4f32 VR128X:$src), v16i8x_info.ImmAllZerosV,
+                         VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rrkz") VK4WM:$mask,
+                                VR128X:$src)>;
+  // Memory
+  def : Pat<(v16i8 (OpNode (loadv4f32 addr:$src))),
+            (!cast<Instruction>(NAME # "Z128rm") addr:$src)>;
+  def : Pat<(MaskOpNode (loadv4f32 addr:$src), (v16i8 VR128X:$src0),
+                         VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmk") VR128X:$src0, VK4WM:$mask,
+                                addr:$src)>;
+  def : Pat<(MaskOpNode (loadv4f32 addr:$src), v16i8x_info.ImmAllZerosV,
+                         VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmkz") VK4WM:$mask, addr:$src)>;
+  // Broadcast
+  def : Pat<(v16i8 (OpNode (v4f32 (X86VBroadcastld32 addr:$src)))),
+            (!cast<Instruction>(NAME # "Z128rmb") addr:$src)>;
+  def : Pat<(MaskOpNode (v4f32 (X86VBroadcastld32 addr:$src)),
+                          (v16i8 VR128X:$src0), VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmbk") VR128X:$src0, VK4WM:$mask,
+                                addr:$src)>;
+  def : Pat<(MaskOpNode (v4f32 (X86VBroadcastld32 addr:$src)),
+                          v16i8x_info.ImmAllZerosV, VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmbkz") VK4WM:$mask, addr:$src)>;
+}
+
+// Group B multiclass: 3-operand bias PS(f32) -> i8 conversion (quarter-size output)
+// bias + f32 source -> i8 dest
+// Reuses avx10_convert_3op_packed from X86InstrAVX10.td for each VL variant.
+multiclass avx10_v2aux_cvt_3op_ps<bits<8> opc, string OpcodeStr,
+                                  SDPatternOperator OpNode,
+                                  SDPatternOperator MaskOpNode> {
+  // Z (512-bit): bias=v64i8(zmm), src=v16f32(zmm), dst=v16i8(xmm)
+  // Element counts match (16), so vselect_mask works directly.
+  defm Z : avx10_convert_3op_packed<opc, OpcodeStr, v16i8x_info,
+             v64i8_info, v16f32_info, OpNode, OpNode, WriteCvtPH2PSZ>,
+             EVEX_V512, EVEX_CD8<32, CD8VF>;
+  // Z256/Z128: use null_frag because element count mismatch between
+  // dest (v16i8) and source (v8f32/v4f32) prevents vselect_mask from
+  // generating correct masked patterns. Explicit Pat patterns below.
+  defm Z256 : avx10_convert_3op_packed<opc, OpcodeStr, v16i8x_info,
+                v32i8x_info, v8f32x_info,
+                null_frag, null_frag, WriteCvtPH2PSZ>,
+                EVEX_V256, EVEX_CD8<32, CD8VF>;
+  defm Z128 : avx10_convert_3op_packed<opc, OpcodeStr, v16i8x_info,
+                v16i8x_info, v4f32x_info,
+                null_frag, null_frag, WriteCvtPH2PSZ>,
+                EVEX_V128, EVEX_CD8<32, CD8VF>;
+
+  // Explicit patterns for Z256 (8 source elements, VK8WM mask)
+  def : Pat<(v16i8 (OpNode (v32i8 VR256X:$src1), (v8f32 VR256X:$src2))),
+            (!cast<Instruction>(NAME # "Z256rr") VR256X:$src1, VR256X:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1), (v8f32 VR256X:$src2),
+                         (v16i8 VR128X:$src0), VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rrk") VR128X:$src0, VK8WM:$mask,
+                                VR256X:$src1, VR256X:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1), (v8f32 VR256X:$src2),
+                         v16i8x_info.ImmAllZerosV, VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rrkz") VK8WM:$mask,
+                                VR256X:$src1, VR256X:$src2)>;
+  // Memory
+  def : Pat<(v16i8 (OpNode (v32i8 VR256X:$src1), (loadv8f32 addr:$src2))),
+            (!cast<Instruction>(NAME # "Z256rm") VR256X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1), (loadv8f32 addr:$src2),
+                         (v16i8 VR128X:$src0), VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmk") VR128X:$src0, VK8WM:$mask,
+                                VR256X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1), (loadv8f32 addr:$src2),
+                         v16i8x_info.ImmAllZerosV, VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmkz") VK8WM:$mask,
+                                VR256X:$src1, addr:$src2)>;
+  // Broadcast
+  def : Pat<(v16i8 (OpNode (v32i8 VR256X:$src1),
+                            (v8f32 (X86VBroadcastld32 addr:$src2)))),
+            (!cast<Instruction>(NAME # "Z256rmb") VR256X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1),
+                          (v8f32 (X86VBroadcastld32 addr:$src2)),
+                          (v16i8 VR128X:$src0), VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmbk") VR128X:$src0, VK8WM:$mask,
+                                VR256X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v32i8 VR256X:$src1),
+                          (v8f32 (X86VBroadcastld32 addr:$src2)),
+                          v16i8x_info.ImmAllZerosV, VK8WM:$mask),
+            (!cast<Instruction>(NAME # "Z256rmbkz") VK8WM:$mask,
+                                VR256X:$src1, addr:$src2)>;
+
+  // Explicit patterns for Z128 (4 source elements, VK4WM mask)
+  def : Pat<(v16i8 (OpNode (v16i8 VR128X:$src1), (v4f32 VR128X:$src2))),
+            (!cast<Instruction>(NAME # "Z128rr") VR128X:$src1, VR128X:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1), (v4f32 VR128X:$src2),
+                         (v16i8 VR128X:$src0), VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rrk") VR128X:$src0, VK4WM:$mask,
+                                VR128X:$src1, VR128X:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1), (v4f32 VR128X:$src2),
+                         v16i8x_info.ImmAllZerosV, VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rrkz") VK4WM:$mask,
+                                VR128X:$src1, VR128X:$src2)>;
+  // Memory
+  def : Pat<(v16i8 (OpNode (v16i8 VR128X:$src1), (loadv4f32 addr:$src2))),
+            (!cast<Instruction>(NAME # "Z128rm") VR128X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1), (loadv4f32 addr:$src2),
+                         (v16i8 VR128X:$src0), VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmk") VR128X:$src0, VK4WM:$mask,
+                                VR128X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1), (loadv4f32 addr:$src2),
+                         v16i8x_info.ImmAllZerosV, VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmkz") VK4WM:$mask,
+                                VR128X:$src1, addr:$src2)>;
+  // Broadcast
+  def : Pat<(v16i8 (OpNode (v16i8 VR128X:$src1),
+                            (v4f32 (X86VBroadcastld32 addr:$src2)))),
+            (!cast<Instruction>(NAME # "Z128rmb") VR128X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1),
+                          (v4f32 (X86VBroadcastld32 addr:$src2)),
+                          (v16i8 VR128X:$src0), VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmbk") VR128X:$src0, VK4WM:$mask,
+                                VR128X:$src1, addr:$src2)>;
+  def : Pat<(MaskOpNode (v16i8 VR128X:$src1),
+                          (v4f32 (X86VBroadcastld32 addr:$src2)),
+                          v16i8x_info.ImmAllZerosV, VK4WM:$mask),
+            (!cast<Instruction>(NAME # "Z128rmbkz") VK4WM:$mask,
+                                VR128X:$src1, addr:$src2)>;
+}
+
+// Group C multiclass: i8 -> f32 expanding conversion (4x expansion, no broadcast)
+multiclass avx10_v2aux_cvt_2op_i8_to_f32<bits<8> opc, string OpcodeStr,
+                                         SDNode OpNode> {
+  defm Z : avx10_convert_2op_nomb_packed<opc, OpcodeStr, v16f32_info,
+                                         v16i8x_info, OpNode, f128mem,
+                                         WriteCvtPH2PSZ>, EVEX_V512;
+  defm Z128 : avx10_convert_2op_nomb_packed<opc, OpcodeStr, v4f32x_info,
+                                            v16i8x_info, OpNode, f32mem,
+                                            WriteCvtPH2PSZ>, EVEX_V128;
+  defm Z256 : avx10_convert_2op_nomb_packed<opc, OpcodeStr, v8f32x_info,
+                                            v16i8x_info, OpNode, f64mem,
+                                            WriteCvtPH2PSZ>, EVEX_V256;
+}
+
+// Group D multiclass: Truncating conversion (reg/mem dest, no masking)
+// Uses MRMDestReg/MRMDestMem since destination can be memory operand.
+// Source is in reg field, destination is in r/m field.
+multiclass avx10_v2aux_cvt_trunc<bits<8> opc, string OpcodeStr,
+                                  X86VectorVTInfo SrcInfo,
+                                  X86VectorVTInfo DestInfo,
+                                  X86MemOperand x86memop,
+                                  SDPatternOperator OpNode> {
+  let hasSideEffects = 0 in {
+    def rr : I<opc, MRMDestReg, (outs DestInfo.RC:$dst),
+               (ins SrcInfo.RC:$src),
+               OpcodeStr # "\t{$src, $dst|$dst, $src}", []>,
+               EVEX, Sched<[WriteCvtPH2PSZ]>;
+    let mayStore = 1 in
+    def mr : I<opc, MRMDestMem, (outs),
+               (ins x86memop:$dst, SrcInfo.RC:$src),
+               OpcodeStr # "\t{$src, $dst|$dst, $src}", []>,
+               EVEX, Sched<[WriteCvtPH2PSZ.Folded]>;
+  }
+
+  // Intrinsic pattern
+  def : Pat<(DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src))),
+            (!cast<Instruction>(NAME # "rr") SrcInfo.RC:$src)>;
+}
+
+// Group F helper: expanding conversion with masking, no broadcast (reg+mem)
+multiclass avx10_v2aux_cvt_expand_masked<bits<8> opc, string OpcodeStr,
+                                         X86VectorVTInfo _dest,
+                                         X86VectorVTInfo _src,
+                                         X86MemOperand x86memop,
+                                         SDPatternOperator OpNode> {
+  let ExeDomain = _dest.ExeDomain in {
+    defm rr : AVX512_maskable<opc, MRMSrcReg, _dest,
+                (outs _dest.RC:$dst),
+                (ins _src.RC:$src),
+                OpcodeStr, "$src", "$src",
+                (_dest.VT (OpNode (_src.VT _src.RC:$src)))>,
+               EVEX, Sched<[WriteCvtPH2PSZ]>;
+    let mayLoad = 1 in
+    defm rm : AVX512_maskable<opc, MRMSrcMem, _dest,
+                (outs _dest.RC:$dst),
+                (ins x86memop:$src),
+                OpcodeStr, "$src", "$src",
+                (_dest.VT (OpNode (_src.VT (load addr:$src))))>,
+               EVEX, Sched<[WriteCvtPH2PSZ.Folded]>;
+  }
+}
+
+// Group F helper: widening conversion with masking (reg-only, 6-bit to 8-bit)
+multiclass avx10_v2aux_cvt_widen_masked<bits<8> opc, string OpcodeStr,
+                                        X86VectorVTInfo _,
+                                        SDPatternOperator OpNode> {
+  let ExeDomain = _.ExeDomain in {
+    defm rr : AVX512_maskable<opc, MRMSrcReg, _,
+                (outs _.RC:$dst),
----------------
ganeshgit wrote:

Done

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


More information about the cfe-commits mailing list