re PR target/57744 (Power8 support has problems with quad word atomic instructions)
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Fri, 28 Jun 2013 16:15:17 +0000 (16:15 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Fri, 28 Jun 2013 16:15:17 +0000 (16:15 +0000)
[gcc]
2013-06-28  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/57744
* config/rs6000/rs6000.h (MODES_TIEABLE_P): Do not allow PTImode
to tie with any other modes.  Eliminate Altivec vector mode tests,
since these are a subset of ALTIVEC or VSX vector modes.  Simplify
code, to return 0 if testing MODE2 for a condition, if we've
already tested MODE1 for the same condition.

[gcc/testsuite]
2013-06-28  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/57744
* gcc.target/powerpc/pr57744.c: New test to make sure lqarx and
stqcx. get even registers.

From-SVN: r200538

gcc/ChangeLog
gcc/config/rs6000/rs6000.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr57744.c [new file with mode: 0644]

index dbd82a2..6c86c25 100644 (file)
@@ -1,3 +1,12 @@
+2013-06-28  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/57744
+       * config/rs6000/rs6000.h (MODES_TIEABLE_P): Do not allow PTImode
+       to tie with any other modes.  Eliminate Altivec vector mode tests,
+       since these are a subset of ALTIVEC or VSX vector modes.  Simplify
+       code, to return 0 if testing MODE2 for a condition, if we've
+       already tested MODE1 for the same condition.
+
 2013-06-28  Marcus Shawcroft  <marcus.shawcroft@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_cannot_force_const_mem): Adjust
index 633d789..98a44aa 100644 (file)
@@ -1180,28 +1180,32 @@ enum data_align { align_abi, align_opt, align_both };
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-   for any hard reg, then this must be 0 for correct output.  */
+   for any hard reg, then this must be 0 for correct output.
+
+   PTImode cannot tie with other modes because PTImode is restricted to even
+   GPR registers, and TImode can go in any GPR as well as VSX registers (PR
+   57744).  */
 #define MODES_TIEABLE_P(MODE1, MODE2)          \
-  (SCALAR_FLOAT_MODE_P (MODE1)                 \
+  ((MODE1) == PTImode                          \
+   ? (MODE2) == PTImode                                \
+   : (MODE2) == PTImode                                \
+   ? 0                                         \
+   : SCALAR_FLOAT_MODE_P (MODE1)               \
    ? SCALAR_FLOAT_MODE_P (MODE2)               \
    : SCALAR_FLOAT_MODE_P (MODE2)               \
-   ? SCALAR_FLOAT_MODE_P (MODE1)               \
+   ? 0                                         \
    : GET_MODE_CLASS (MODE1) == MODE_CC         \
    ? GET_MODE_CLASS (MODE2) == MODE_CC         \
    : GET_MODE_CLASS (MODE2) == MODE_CC         \
-   ? GET_MODE_CLASS (MODE1) == MODE_CC         \
+   ? 0                                         \
    : SPE_VECTOR_MODE (MODE1)                   \
    ? SPE_VECTOR_MODE (MODE2)                   \
    : SPE_VECTOR_MODE (MODE2)                   \
-   ? SPE_VECTOR_MODE (MODE1)                   \
+   ? 0                                         \
    : ALTIVEC_OR_VSX_VECTOR_MODE (MODE1)                \
    ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE2)                \
    : ALTIVEC_OR_VSX_VECTOR_MODE (MODE2)                \
-   ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE1)                \
-   : ALTIVEC_VECTOR_MODE (MODE1)               \
-   ? ALTIVEC_VECTOR_MODE (MODE2)               \
-   : ALTIVEC_VECTOR_MODE (MODE2)               \
-   ? ALTIVEC_VECTOR_MODE (MODE1)               \
+   ? 0                                         \
    : 1)
 
 /* Post-reload, we can't use any new AltiVec registers, as we already
index 9e7d857..c0b5284 100644 (file)
@@ -1,3 +1,9 @@
+2013-06-28  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/57744
+       * gcc.target/powerpc/pr57744.c: New test to make sure lqarx and
+       stqcx. get even registers.
+
 2013-06-28  Marc Glisse  <marc.glisse@inria.fr>
 
        PR c++/57509
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57744.c b/gcc/testsuite/gcc.target/powerpc/pr57744.c
new file mode 100644 (file)
index 0000000..d1522f7
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O3" } */
+
+typedef unsigned U_16 __attribute__((mode(TI)));
+
+extern int libat_compare_exchange_16 (U_16 *, U_16 *, U_16, int, int)
+  __attribute__((__noinline__));
+
+/* PR 57744: lqarx/stqcx needs even/odd register pairs.  The assembler will
+   complain if the compiler gets an odd/even register pair.  Create a function
+   which has the 16 byte compare and exchange instructions, but don't actually
+   execute it, so that we can detect these failures on older machines. */
+
+int
+libat_compare_exchange_16 (U_16 *mptr, U_16 *eptr, U_16 newval,
+         int smodel, int fmodel __attribute__((unused)))
+{
+  if (((smodel) == 0))
+    return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 0, 0);
+  else if (((smodel) != 5))
+    return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 4, 0);
+  else
+    return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 5, 0);
+}
+
+U_16 a = 1, b = 1, c = -2;
+volatile int do_test = 0;
+
+int main (void)
+{
+  if (do_test && !libat_compare_exchange_16 (&a, &b, c, 0, 0))
+    aborrt ();
+
+  return 0;
+}