aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 371528b0405..8f6679ed262 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13233,7 +13233,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)
@@ -13252,6 +13256,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;
}