aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wilco.dijkstra@arm.com>2024-01-16 16:27:02 +0000
committerWilco Dijkstra <wilco.dijkstra@arm.com>2024-01-16 17:12:48 +0000
commitdb4e496aadf1d7ab1c5af24410394d1551ddd3f0 (patch)
tree9c70c875e87e53441175b90183c15b7154e9004e
parent4bd09ce06f50d266c992c984cc993384d5e6655e (diff)
downloadgcc-db4e496aadf1d7ab1c5af24410394d1551ddd3f0.zip
gcc-db4e496aadf1d7ab1c5af24410394d1551ddd3f0.tar.gz
gcc-db4e496aadf1d7ab1c5af24410394d1551ddd3f0.tar.bz2
AArch64: Reassociate CONST in address expressions
GCC tends to optimistically create CONST of globals with an immediate offset. However it is almost always better to CSE addresses of globals and add immediate offsets separately (the offset could be merged later in single-use cases). Splitting CONST expressions with an index in aarch64_legitimize_address fixes part of PR112573. gcc/ChangeLog: PR target/112573 * config/aarch64/aarch64.cc (aarch64_legitimize_address): Reassociate badly formed CONST expressions. gcc/testsuite/ChangeLog: PR target/112573 * gcc.target/aarch64/pr112573.c: Add new test.
-rw-r--r--gcc/config/aarch64/aarch64.cc11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr112573.c15
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 7d1f8c6..e6bd3fd 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -12617,6 +12617,17 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x */, machine_mode mode)
not to split a CONST for some forms of address expression, otherwise
it will generate sub-optimal code. */
+ /* First split X + CONST (base, offset) into (base + X) + offset. */
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST)
+ {
+ poly_int64 offset;
+ rtx base = strip_offset (XEXP (x, 1), &offset);
+
+ base = expand_binop (Pmode, add_optab, base, XEXP (x, 0),
+ NULL_RTX, true, OPTAB_DIRECT);
+ x = plus_constant (Pmode, base, offset);
+ }
+
if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
{
rtx base = XEXP (x, 0);
diff --git a/gcc/testsuite/gcc.target/aarch64/pr112573.c b/gcc/testsuite/gcc.target/aarch64/pr112573.c
new file mode 100644
index 0000000..be04c0c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr112573.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-section-anchors" } */
+
+char a[100];
+
+void f1 (int x, int y)
+{
+ *((a + y) + 3) = x;
+ *((a + y) + 2) = x;
+ *((a + y) + 1) = x;
+ *((a + y) + 0) = x;
+}
+
+/* { dg-final { scan-assembler-times "strb" 4 } } */
+/* { dg-final { scan-assembler-times "adrp" 1 } } */