From 65c98fdec722720ae9b2a6765232fe4535e06d4e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 2 Feb 2016 11:59:17 +1030 Subject: [PATCH] [RS6000] lqarx and stqcx. registers 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. PR target/69548 gcc/ * config/rs6000/predicates.md (quad_int_reg_operand): Don't allow subregs. gcc/testsuite/ * gcc.target/powerpc/pr69548.c: New test. From-SVN: r233065 --- gcc/ChangeLog | 6 ++++++ gcc/config/rs6000/predicates.md | 13 ++++++------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/powerpc/pr69548.c | 11 +++++++++++ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr69548.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d89607433b..b061339ae06 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2016-02-02 Alan Modra + PR target/69548 + * config/rs6000/predicates.md (quad_int_reg_operand): Don't + allow subregs. + +2016-02-02 Alan Modra + PR target/68662 * config/rs6000/rs6000.c (need_toc_init): New var, set it whenever toc_label_name used. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 5adc4de6a31..072291ef7d0 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/ChangeLog b/gcc/testsuite/ChangeLog index 1f8ddd09688..c96277c9381 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-02 Alan Modra + + PR target/69548 + * gcc.target/powerpc/pr69548.c: New test. + 2016-02-01 Jakub Jelinek PR rtl-optimization/69592 diff --git a/gcc/testsuite/gcc.target/powerpc/pr69548.c b/gcc/testsuite/gcc.target/powerpc/pr69548.c new file mode 100644 index 00000000000..439f588b874 --- /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); +} -- 2.11.4.GIT