]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Return true for (SUBREG (MEM....)) in register_no_elim_operand [PR105927]
authorUros Bizjak <ubizjak@gmail.com>
Mon, 13 Jun 2022 15:08:18 +0000 (17:08 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Mon, 13 Jun 2022 15:10:49 +0000 (17:10 +0200)
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.

gcc/config/i386/predicates.md
gcc/testsuite/gcc.target/i386/pr105927.c [new file with mode: 0644]

index 848a79a8d163c9371275c1a80286f7a086e50a24..128144f1050f3e12a95321ed1f6ba387001ba0bf 100644 (file)
 {
   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),
 {
   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 (file)
index 0000000..6024618
--- /dev/null
@@ -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);
+}