public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RS6000] lqarx and stqcx. registers
@ 2016-01-31 22:28 Alan Modra
  2016-02-01 17:59 ` David Edelsohn
  0 siblings, 1 reply; 2+ messages in thread
From: Alan Modra @ 2016-01-31 22:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn, Michael Meissner

lqarx RT and stqcx. RS are valid only with even numbered gprs.  The
predicate to enforce this happens to allow a loophole, closed by this
patch.

This pattern created by combine:
Trying 8 -> 9:
Successfully matched this instruction:
(set (subreg:PTI (reg:TI 155 [ D.2357 ]) 0)
    (unspec_volatile:PTI [
            (mem/v:TI (reg/v/f:DI 157 [ mptr ]) [-1  S16 A128])
        ] UNSPECV_LL))

is seen by reload as needing to reload pseudo 155 in TI mode, which
has no requirement that the reg be even.  Apparently, nothing checks
the predicate again after reload.

We only see this problem on gcc-5 and gcc-4.9, because on gcc-6 we
don't define WORD_REGISTER_OPERATIONS and combine happens to have a
bug in simplify_set that prevents it creating the problem subregs.
See https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02377.html

Bootstrapped and regression tested powerpc64-linux biarch on master
both with and without the combine bug, and on gcc-5.  OK for master
and active branches?

gcc/
	PR target/69548
	* config/rs6000/predicates.md (quad_int_reg_operand): Don't
	allow subregs.
gcc/testsuite/
	* gcc.target/powerpc/pr69548.c: New test.

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b8f14fd..302303c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -375,20 +375,19 @@
 
 ;; Return 1 if op is a general purpose register that is an even register
 ;; which suitable for a load/store quad operation
+;; Subregs are not allowed here because when they are combine can
+;; create (subreg:PTI (reg:TI pseudo)) which will cause reload to
+;; think the innermost reg needs reloading, in TImode instead of
+;; PTImode.  So reload will choose a reg in TImode which has no
+;; requirement that the reg be even.
 (define_predicate "quad_int_reg_operand"
-  (match_operand 0 "register_operand")
+  (match_code "reg")
 {
   HOST_WIDE_INT r;
 
   if (!TARGET_QUAD_MEMORY && !TARGET_QUAD_MEMORY_ATOMIC)
     return 0;
 
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-
-  if (!REG_P (op))
-    return 0;
-
   r = REGNO (op);
   if (r >= FIRST_PSEUDO_REGISTER)
     return 1;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr69548.c b/gcc/testsuite/gcc.target/powerpc/pr69548.c
new file mode 100644
index 0000000..439f588
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr69548.c
@@ -0,0 +1,11 @@
+/* { dg-do assemble { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -Os -mbig" } */
+
+__int128
+quad_exchange (__int128 *ptr, __int128 newval)
+{
+  return __atomic_exchange_n (ptr, newval, __ATOMIC_RELAXED);
+}

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [RS6000] lqarx and stqcx. registers
  2016-01-31 22:28 [RS6000] lqarx and stqcx. registers Alan Modra
@ 2016-02-01 17:59 ` David Edelsohn
  0 siblings, 0 replies; 2+ messages in thread
From: David Edelsohn @ 2016-02-01 17:59 UTC (permalink / raw)
  To: Alan Modra; +Cc: GCC Patches, Michael Meissner

On Sun, Jan 31, 2016 at 5:28 PM, Alan Modra <amodra@gmail.com> wrote:
> lqarx RT and stqcx. RS are valid only with even numbered gprs.  The
> predicate to enforce this happens to allow a loophole, closed by this
> patch.
>
> This pattern created by combine:
> Trying 8 -> 9:
> Successfully matched this instruction:
> (set (subreg:PTI (reg:TI 155 [ D.2357 ]) 0)
>     (unspec_volatile:PTI [
>             (mem/v:TI (reg/v/f:DI 157 [ mptr ]) [-1  S16 A128])
>         ] UNSPECV_LL))
>
> is seen by reload as needing to reload pseudo 155 in TI mode, which
> has no requirement that the reg be even.  Apparently, nothing checks
> the predicate again after reload.
>
> We only see this problem on gcc-5 and gcc-4.9, because on gcc-6 we
> don't define WORD_REGISTER_OPERATIONS and combine happens to have a
> bug in simplify_set that prevents it creating the problem subregs.
> See https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02377.html
>
> Bootstrapped and regression tested powerpc64-linux biarch on master
> both with and without the combine bug, and on gcc-5.  OK for master
> and active branches?
>
> gcc/
>         PR target/69548
>         * config/rs6000/predicates.md (quad_int_reg_operand): Don't
>         allow subregs.
> gcc/testsuite/
>         * gcc.target/powerpc/pr69548.c: New test.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-02-01 17:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-31 22:28 [RS6000] lqarx and stqcx. registers Alan Modra
2016-02-01 17:59 ` David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).