[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
This commit is contained in:
Kyrylo Tkachov 2016-03-03 17:25:43 +00:00 committed by Kyrylo Tkachov
parent 97ecdb46b1
commit 0ba3bfa2b0
4 changed files with 54 additions and 1 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 } } */