aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2025-01-17 15:56:29 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2025-01-17 15:57:12 -0500
commit9f009e8865cda01310c52f7ec8bdaa3c557a2745 (patch)
treeccc7deac792a3a4430de37c5b1db9051e695c1bb
parentd8a31b5bead0c64d7e4a59d6834bc649f68de765 (diff)
downloadgcc-9f009e8865cda01310c52f7ec8bdaa3c557a2745.zip
gcc-9f009e8865cda01310c52f7ec8bdaa3c557a2745.tar.gz
gcc-9f009e8865cda01310c52f7ec8bdaa3c557a2745.tar.bz2
[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.
-rw-r--r--gcc/lra-constraints.cc17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr118067-2.c16
2 files changed, 33 insertions, 0 deletions
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 3d5abcf..cd19da2 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 0000000..831871d
--- /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;
+}