https://gcc.gnu.org/g:9f009e8865cda01310c52f7ec8bdaa3c557a2745

commit r15-7008-g9f009e8865cda01310c52f7ec8bdaa3c557a2745
Author: Vladimir N. Makarov <vmaka...@redhat.com>
Date:   Fri Jan 17 15:56:29 2025 -0500

    [PR118067][LRA]: Check secondary memory mode for the reg class
    
      This is the second patch for the PR for the new test.  The patch
    solves problem in the case when secondary memory mode (SImode in the
    PR test) returned by hook secondary_memory_needed_mode can not be used
    for reg class (ALL_MASK_REGS) involved in secondary memory moves.  The
    patch uses reg mode instead of one returned by
    secondary_memory_needed_mode in this case.
    
    gcc/ChangeLog:
    
            PR rtl-optimization/118067
            * lra-constraints.cc (invalid_mode_reg_p): New function.
            (curr_insn_transform): Use it to check mode returned by target
            secondary_memory_needed_mode.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr118067-2.c: New.

Diff:
---
 gcc/lra-constraints.cc                     | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr118067-2.c | 16 ++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 3d5abcfaeb0b..cd19da294db3 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4129,6 +4129,19 @@ swap_operands (int nop)
   lra_update_dup (curr_id, nop + 1);
 }
 
+/* Return TRUE if X is a (subreg of) reg and there are no hard regs of X class
+   which can contain value of MODE.  */
+static bool invalid_mode_reg_p (enum machine_mode mode, rtx x)
+{
+  if (SUBREG_P (x))
+    x = SUBREG_REG (x);
+  if (! REG_P (x))
+    return false;
+  enum reg_class rclass = get_reg_class (REGNO (x));
+  return hard_reg_set_subset_p (ira_prohibited_class_mode_regs[rclass][mode],
+                               reg_class_contents[rclass]);
+}
+
 /* Main entry point of the constraint code: search the body of the
    current insn to choose the best alternative.  It is mimicking insn
    alternative cost calculation model of former reload pass.  That is
@@ -4389,6 +4402,10 @@ curr_insn_transform (bool check_only_p)
       rld = partial_subreg_p (GET_MODE (src), GET_MODE (dest)) ? src : dest;
       rld_mode = GET_MODE (rld);
       sec_mode = targetm.secondary_memory_needed_mode (rld_mode);
+      if (rld_mode != sec_mode
+         && (invalid_mode_reg_p (sec_mode, dest)
+             || invalid_mode_reg_p (sec_mode, src)))
+       sec_mode = rld_mode;
       new_reg = lra_create_new_reg (sec_mode, NULL_RTX, NO_REGS, NULL,
                                    "secondary");
       /* If the mode is changed, it should be wider.  */
diff --git a/gcc/testsuite/gcc.target/i386/pr118067-2.c 
b/gcc/testsuite/gcc.target/i386/pr118067-2.c
new file mode 100644
index 000000000000..831871db0b43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr118067-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O -fno-split-wide-types -mavx512f -mcpu=k8" } */
+
+typedef unsigned short U __attribute__((__vector_size__(64)));
+typedef int V __attribute__((__vector_size__(64)));
+typedef __int128 W __attribute__((__vector_size__(64)));
+
+W
+foo(U u, V v)
+{
+  W w;
+  /* __asm__ volatile ("" : "=v"(w)); prevents the -Wuninitialized warning */
+  u[0] >>= 1;
+  v %= (V)w;
+  return (W)u + (W)v;
+}

Reply via email to