i386: Return true for (SUBREG (MEM....)) in register_no_elim_operand [PR105927]

Message ID CAFULd4YKkFpFsp=D1txi44UVgib8HZTsuoDfrGy3=1zVtX91Fw@mail.gmail.com
State Committed
Commit b3dd7d8b48227d3489039ca66b6c0ea2da743255
Headers
Series i386: Return true for (SUBREG (MEM....)) in register_no_elim_operand [PR105927] |

Commit Message

Uros Bizjak June 13, 2022, 3:15 p.m. UTC
  Under certain conditions register_operand predicate also allows
subregs of memory operands.  When RTL checking is enabled, these
will fail with REGNO (op).

Allow subregs of memory operands, these are guaranteed
to be reloaded to a register.

2022-06-13  Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog:

    PR target/105927
    * config/i386/predicates.md (register_no_elim_operand):
    Return true for subreg of a memory operand.

gcc/testsuite/ChangeLog:

    PR target/105927
    * gcc.target/i386/pr105927.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Pushed to master.

Uros.
  

Patch

diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 848a79a8d16..128144f1050 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -672,6 +672,12 @@  (define_predicate "register_no_elim_operand"
 {
   if (SUBREG_P (op))
     op = SUBREG_REG (op);
+
+  /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
+     because it is guaranteed to be reloaded into one.  */
+  if (MEM_P (op))
+    return true;
+
   return !(op == arg_pointer_rtx
 	   || op == frame_pointer_rtx
 	   || IN_RANGE (REGNO (op),
@@ -685,6 +691,7 @@  (define_predicate "index_register_operand"
 {
   if (SUBREG_P (op))
     op = SUBREG_REG (op);
+
   if (reload_completed)
     return REG_OK_FOR_INDEX_STRICT_P (op);
   else
diff --git a/gcc/testsuite/gcc.target/i386/pr105927.c b/gcc/testsuite/gcc.target/i386/pr105927.c
new file mode 100644
index 00000000000..602461806fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr105927.c
@@ -0,0 +1,18 @@ 
+/* PR target/105927 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O1 -fno-tree-dce -mtune=k6-3 -msse2" } */
+
+typedef _Float16 __attribute__((__vector_size__(4))) U;
+typedef _Float16 __attribute__((__vector_size__(2))) V;
+typedef short __attribute__((__vector_size__(4))) W;
+V v;
+U u;
+
+extern void bar(W i);
+
+void
+foo(void)
+{
+  U x = __builtin_shufflevector(v, u, 2, 0);
+  bar(x >= 0);
+}