https://gcc.gnu.org/g:5baf295ebdad345f13c5371196d808846219575a
commit 5baf295ebdad345f13c5371196d808846219575a Author: Michael Meissner <[email protected]> Date: Sat Jul 18 02:55:45 2026 -0400 DMF patch 12 (note, the patch adding UNSPEC_DMF_EXTRACT1024 has been removed). 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..c0aa885ac019 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_DM_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 } } */
