This is one more patch to solve
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118067
with different -mcpu used.
The patch was successfully bootstrapped and tested on x86-64, aarch64,
and ppc64le.
commit 9f009e8865cda01310c52f7ec8bdaa3c557a2745
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 --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 3d5abcfaeb0..cd19da294db 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 00000000000..831871db0b4
--- /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;
+}