From 1feed8925f6290bb732fca6e7bce096b92321a92 Mon Sep 17 00:00:00 2001 From: ktkachov Date: Thu, 3 Mar 2016 17:25:43 +0000 Subject: [PATCH] [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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233941 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 20 +++++++++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/arm/pr69904.c | 24 ++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr69904.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb5e396a448..9ae55001ca9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-03-03 Kyrylo Tkachov + + PR rtl-optimization/69904 + * config/arm/arm.c (arm_cannot_copy_insn_p): + Return true for load-exclusive instructions. + 2016-03-03 Jakub Jelinek PR target/70021 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 94893439015..c868490d768 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 5ffe64f65f3..a3592de40f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-03-03 Kyrylo Tkachov + + PR rtl-optimization/69904 + * gcc.target/arm/pr69904.c: New test. + 2016-03-03 Jakub Jelinek 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 00000000000..24fe844d58e --- /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 + +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 } } */ -- 2.11.4.GIT