aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-03-03 17:25:43 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2016-03-03 17:25:43 +0000
commit0ba3bfa2b04d68ab9c727bdf1331b87919084d7c (patch)
treefbf3a3d4d054812982ca8f98dfaa6f1efc5efe20
parent97ecdb46b1261d34e015df1f6eff20e069ca9bbf (diff)
downloadgcc-0ba3bfa2b04d68ab9c727bdf1331b87919084d7c.zip
gcc-0ba3bfa2b04d68ab9c727bdf1331b87919084d7c.tar.gz
gcc-0ba3bfa2b04d68ab9c727bdf1331b87919084d7c.tar.bz2
[ARM] PR rtl-optimization/69904: Disallow copying/duplicating of load-exclusive operations
PR rtl-optimization/69904 * config/arm/arm.c (arm_cannot_copy_insn_p): Return true for load-exclusive instructions. * gcc.target/arm/pr69904.c: New test. From-SVN: r233941
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr69904.c24
4 files changed, 54 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb5e396..9ae5500 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-03-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR rtl-optimization/69904
+ * config/arm/arm.c (arm_cannot_copy_insn_p):
+ Return true for load-exclusive instructions.
+
2016-03-03 Jakub Jelinek <jakub@redhat.com>
PR target/70021
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9489343..c868490 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13263,7 +13263,11 @@ tls_mentioned_p (rtx x)
}
}
-/* Must not copy any rtx that uses a pc-relative address. */
+/* Must not copy any rtx that uses a pc-relative address.
+ Also, disallow copying of load-exclusive instructions that
+ may appear after splitting of compare-and-swap-style operations
+ so as to prevent those loops from being transformed away from their
+ canonical forms (see PR 69904). */
static bool
arm_cannot_copy_insn_p (rtx_insn *insn)
@@ -13282,6 +13286,20 @@ arm_cannot_copy_insn_p (rtx_insn *insn)
|| XINT (x, 1) == UNSPEC_PIC_UNIFIED))
return true;
}
+
+ rtx set = single_set (insn);
+ if (set)
+ {
+ rtx src = SET_SRC (set);
+ if (GET_CODE (src) == ZERO_EXTEND)
+ src = XEXP (src, 0);
+
+ /* Catch the load-exclusive and load-acquire operations. */
+ if (GET_CODE (src) == UNSPEC_VOLATILE
+ && (XINT (src, 1) == VUNSPEC_LL
+ || XINT (src, 1) == VUNSPEC_LAX))
+ return true;
+ }
return false;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5ffe64f..a3592de 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR rtl-optimization/69904
+ * gcc.target/arm/pr69904.c: New test.
+
2016-03-03 Jakub Jelinek <jakub@redhat.com>
PR target/70021
diff --git a/gcc/testsuite/gcc.target/arm/pr69904.c b/gcc/testsuite/gcc.target/arm/pr69904.c
new file mode 100644
index 0000000..24fe844
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr69904.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -marm" } */
+/* { dg-require-effective-target arm_arch_v7a_ok } */
+/* { dg-add-options arm_arch_v7a } */
+
+/* Make sure that RTL optimizers don't do any unexpected transformations
+ on the compare_exchange loop. */
+
+#include <stdatomic.h>
+
+atomic_uint foo;
+atomic_uint bar;
+int glob;
+
+int
+main (void)
+{
+ glob = atomic_compare_exchange_strong (&foo, &bar, 0);
+ return glob;
+}
+
+/* { dg-final { scan-assembler-times "dmb\tish" 2 } } */
+/* { dg-final { scan-assembler-times "ldrex\t" 1 } } */
+/* { dg-final { scan-assembler-times "strex\t" 1 } } */