[gcc r17-2666] rs6000: Add DMR extract builtins for Dense Math support

Surya Kumari Jangala via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:abbc5b3ee1241069e011b51174e229bf523bcc6a

commit r17-2666-gabbc5b3ee1241069e011b51174e229bf523bcc6a
Author: Surya Kumari Jangala <[email protected]>
Date:   Thu Jul 23 02:33:09 2026 -0500

    rs6000: Add DMR extract builtins for Dense Math support
    
    Add two new builtins for extracting data from 1024-bit Dense Math
    Registers (DMRs):
    
      - __builtin_dmr_extract512 (void *, dmr1024 *, const int<2>):
        extracts one 512-bit half of a DMR into four 128-bit vectors.
      - __builtin_disassemble_dmr (void *, dmr1024 *):
        extracts both 512-bit halves of a DMR into eight 128-bit vectors.
    
    2026-07-16  Surya Kumari Jangala  <[email protected]>
    
    gcc:
            * config/rs6000/rs6000-builtins.def (__builtin_dmr_extract512): New
            built-in.
            (__builtin_disassemble_dmr): Likewise.
            (__builtin_dmr_extract512_internal): New internal built-in.
            * config/rs6000/rs6000-builtin.cc (rs6000_gimple_fold_mma_builtin):
            Exempt RS6000_BIF_DISASSEMBLE_DMR from the early-return guard.
            Generate appropriate gimple code for the extract builtins.
    
    gcc/testsuite:
            * gcc.target/powerpc/dmf-extract512.c: New test.
            * gcc.target/powerpc/dmf-disassemble-dmr.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-builtin.cc                | 71 +++++++++++++++++++++-
 gcc/config/rs6000/rs6000-builtins.def              |  9 +++
 .../gcc.target/powerpc/dmf-disassemble-dmr.c       | 24 ++++++++
 gcc/testsuite/gcc.target/powerpc/dmf-extract512.c  | 20 ++++++
 4 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 0c6d961d7a7d..d8eef2b65fe7 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -1131,7 +1131,8 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
   if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE
       && fncode != RS6000_BIF_LXVP
       && fncode != RS6000_BIF_STXVP
-      && fncode != RS6000_BIF_DMMR)
+      && fncode != RS6000_BIF_DMMR
+      && fncode != RS6000_BIF_DISASSEMBLE_DMR)
     return false;
 
   bifdata *bd = &rs6000_builtin_info[fncode];
@@ -1139,6 +1140,74 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
   gimple *new_call;
   tree new_decl;
 
+  if (fncode == RS6000_BIF_DMF_EXTRACT512
+      || fncode == RS6000_BIF_DISASSEMBLE_DMR)
+    {
+      unsigned num_extract512;
+      push_gimplify_context (true);
+      tree dst_ptr = gimple_call_arg (stmt, 0);
+      tree src_ptr = gimple_call_arg (stmt, 1);
+      tree src_type = build_pointer_type (dmr1024_type_node);
+
+      if (TREE_TYPE (src_ptr) != src_type)
+       src_ptr = build1 (NOP_EXPR, src_type, src_ptr);
+
+      /* The following code will ensure we are sending *src as parameter.  */
+      tree src = make_ssa_name (TREE_TYPE (src_type));
+      gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq);
+
+      /* Now we should call the internal builtin RS6000_BIF_DMF_EXTRACT512_INTERNAL.  */
+      if (fncode == RS6000_BIF_DISASSEMBLE_DMR)
+       num_extract512 = 2;
+      else
+       num_extract512 = 1;
+
+      tree extract_decl = rs6000_builtin_decls[RS6000_BIF_DMF_EXTRACT512_INTERNAL];
+
+      for (unsigned i = 0; i < num_extract512; i++)
+	{
+	  tree const_arg;
+	  if (fncode == RS6000_BIF_DISASSEMBLE_DMR)
+	    const_arg = build_int_cstu (uint16_type_node, i);
+	  else
+	    const_arg = gimple_call_arg (stmt, 2);
+
+	  /* Create call.  */
+	  new_call = gimple_build_call (extract_decl, 2, src, const_arg);
+	  /* Create a tmp reg to denote lhs of call.  */
+	  tree lhs = make_ssa_name (vector_quad_type_node);
+
+	  /* lhs = new_call  */
+	  gimple_call_set_lhs (new_call, lhs);
+
+	  /* Add gimple stmt to gimple sequence.  */
+	  gimple_seq_add_stmt (&new_seq, new_call);
+
+	  /* Now lhs contains the 512-bit value in vector_quad. We have to now
+	     split up the vector_quad into individual vectors.  */
+
+	  new_decl = rs6000_builtin_decls[RS6000_BIF_DISASSEMBLE_ACC_INTERNAL];
+	  tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node,
+						       ptr_mode, true);
+
+	  tree dst_base = build1 (NOP_EXPR, dst_type, dst_ptr);
+	  for (unsigned j = 0; j < 4; j++)
+	    {
+	      tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base,
+				 build_int_cst (dst_type, j * 16 + i * 64));
+	      tree dstssa = make_ssa_name (unsigned_V16QI_type_node);
+	      new_call = gimple_build_call (new_decl, 2, lhs,
+					    build_int_cstu (uint16_type_node, j));
+	      gimple_call_set_lhs (new_call, dstssa);
+	      gimple_seq_add_stmt (&new_seq, new_call);
+	      gimplify_assign (dst, dstssa, &new_seq);
+	    }
+	}
+      pop_gimplify_context (NULL);
+      gsi_replace_with_seq (gsi, new_seq, true);
+      return true;
+    }
+
   /* Compatibility built-ins; we used to call these
      __builtin_mma_{dis,}assemble_pair, but now we call them
      __builtin_vsx_{dis,}assemble_pair.  Handle the old versions.  */
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 2c0bc1d0119b..f949db410634 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -4121,6 +4121,15 @@
   dmr1024 __builtin_build_dmr_internal (vuc, vuc, vuc, vuc, vuc, vuc, vuc, vuc);
     BUILD_DMR_INTERNAL dmf_build_dmr {dm}
 
+  void __builtin_dmr_extract512 (void *, dmr1024 *, const int<2>);
+    DMF_EXTRACT512 nothing {dm,dmint}
+
+  v512 __builtin_dmr_extract512_internal (dmr1024, const int<2>);
+    DMF_EXTRACT512_INTERNAL dm_extract512 {dm}
+
+  void __builtin_disassemble_dmr (void *, dmr1024 *);
+    DISASSEMBLE_DMR nothing {dm}
+
   void __builtin_mma_dmxvi8gerx4 (dmr1024 *, v256, vuc);
     DMXVI8GERX4 nothing {dm,dmint}
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-disassemble-dmr.c b/gcc/testsuite/gcc.target/powerpc/dmf-disassemble-dmr.c
new file mode 100644
index 000000000000..64a966ea61e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmf-disassemble-dmr.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+typedef unsigned char vec_t __attribute__((vector_size(16)));
+
+void
+bar (vec_t *dst, __dmr1024 *src)
+{
+  vec_t res[8];
+  __builtin_disassemble_dmr (res, src);
+  dst[0] = res[0];
+  dst[2] = res[1];
+  dst[4] = res[2];
+  dst[6] = res[3];
+  dst[8] = res[4];
+  dst[10] = res[5];
+  dst[12] = res[6];
+  dst[14] = res[7];
+}
+
+/* { dg-final { scan-assembler-times {\mdmxxextfdmr512\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstxv\M} 8 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-extract512.c b/gcc/testsuite/gcc.target/powerpc/dmf-extract512.c
new file mode 100644
index 000000000000..2b112c2725cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dmf-extract512.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_future_compile_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=future -O2" } */
+
+typedef unsigned char vec_t __attribute__((vector_size(16)));
+
+void
+bar (vec_t *dst, __dmr1024 *src)
+{
+  vec_t res[4];
+  __builtin_dmr_extract512 (res, src, 0);
+  dst[0] = res[0];
+  dst[2] = res[1];
+  dst[4] = res[2];
+  dst[6] = res[3];
+}
+
+/* { dg-final { scan-assembler-times {\mdmxxextfdmr512\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mstxv\M} 4 } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.