> -----Original Message-----
> From: Wilco Dijkstra <[email protected]>
> Sent: 05 February 2026 17:25
> To: Alex Coplan <[email protected]>; Alice Carlotti
> <[email protected]>; Andrew Pinski
> <[email protected]>; Kyrylo Tkachov
> <[email protected]>; Tamar Christina <[email protected]>
> Cc: GCC Patches <[email protected]>
> Subject: [PATCH] AArch64: Use anchors for vector constants [PR 121240]
>
>
> Enable anchors for vector constants - like FP, expand vector constants early
> and place them in the constdata section. Performance on SPECFP2017 is
> ~0.03%
> better. There is a slight 0.08% increase in codesize due to extra const data
> and a latent CSE issue which results in aarch64/vect-cse-codegen.c failing.
>
> Passes regress, OK for commit?
How can it both pass regress and have a test failing test :)
Isn't the problem that now we force vectors to memory so early that CSE
no longer sees the CONST_VECTOR, which is the thing it was taught to track?
I might be misunderstanding but the goal is to have these lowered before
reload right? which is what's currently forcing them, and so we lose the
combination
of anchors?
So then I have three questions:
1. Can we then extend CSE to track the vectors behind a MEM, the REG_EQUAL notes
still seems to be there and could be used perhaps?
2. Could we instead of forcing them at expand, force them after CSE, for
instance
split 1 that runs quite early too.
3. By forcing them to memory so early, does RTL's LIM still hoist them? Or does
it
think there's a side-effect now?
As you can tell from that the testcase is very specific, this came from a
non-SPECCPU
intrinsics workload that this now regresses.
Thanks,
Tamar
>
> gcc:
> PR target/121240
> * config/aarch64/aarch64-simd.md (mov<mode>): Expand vector
> constants
> early.
> * config/aarch64/aarch64.cc (aarch64_select_rtx_section): Force
> vector immediates <= 16 bytes to constdata.
>
> gcc/testsuite:
> PR target/121240
> * gcc.target/aarch64/const_create_using_fmov.c: Adjust anchor label.
> * gcc.target/aarch64/pr121240.c: Add new test.
> * gcc.target/aarch64/vec-init-single-const.c: Adjust anchor label.
>
> ---
>
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index
> 505e8b1126fa021a22f1ee37cecae1fc8098ae78..264b681f9f2d79e6e8e478
> a0ba490a4016c1031b 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -70,11 +70,22 @@ (define_expand "mov<mode>"
> contains CONST_POLY_INTs), build it up from individual elements instead.
> We should only need to do this before RA; aarch64_legitimate_constant_p
> should ensure that we don't try to rematerialize the constant later. */
> - if (GET_CODE (operands[1]) == CONST_VECTOR
> - && targetm.cannot_force_const_mem (<MODE>mode, operands[1]))
> + if (GET_CODE (operands[1]) == CONST_VECTOR)
> {
> - aarch64_expand_vector_init (operands[0], operands[1]);
> - DONE;
> + if (targetm.cannot_force_const_mem (<MODE>mode, operands[1]))
> + {
> + aarch64_expand_vector_init (operands[0], operands[1]);
> + DONE;
> + }
> + else if (!aarch64_simd_imm_zero (operands[1], <MODE>mode)
> + && !aarch64_simd_special_constant_p (operands[1],
> <MODE>mode)
> + && !aarch64_simd_valid_mov_imm (operands[1]))
> + {
> + /* Expand into a literal load using anchors. */
> + operands[1] = force_const_mem (<MODE>mode, operands[1]);
> + emit_move_insn (operands[0], operands[1]);
> + DONE;
> + }
> }
> "
> )
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index
> 29d2400a6e9d6277ee5ed283ff8e11041d920435..f5285ed45962f3fe79534
> 8cc77534b3dfa010b52 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -14311,8 +14311,8 @@ aarch64_select_rtx_section (machine_mode
> mode,
> return function_section (current_function_decl);
>
> /* When using anchors for constants use the readonly section. */
> - if ((CONST_INT_P (x) || CONST_DOUBLE_P (x))
> - && known_le (GET_MODE_SIZE (mode), 8))
> + if ((CONST_INT_P (x) || CONST_DOUBLE_P (x) || CONST_VECTOR_P (x))
> + && known_le (GET_MODE_SIZE (mode), 16))
> return readonly_data_section;
>
> return default_elf_select_rtx_section (mode, x, align);
> diff --git a/gcc/testsuite/gcc.target/aarch64/const_create_using_fmov.c
> b/gcc/testsuite/gcc.target/aarch64/const_create_using_fmov.c
> index
> e080afed8aa3578660027979335bfc859ca6bc91..98060556e80d67835039
> b3e6ec9d2124357d0d06 100644
> --- a/gcc/testsuite/gcc.target/aarch64/const_create_using_fmov.c
> +++ b/gcc/testsuite/gcc.target/aarch64/const_create_using_fmov.c
> @@ -78,8 +78,8 @@ uint16x8_t f5() {
>
> /*
> ** f6:
> -** adrp x0, \.LC0
> -** ldr q0, \[x0, #:lo12:\.LC0\]
> +** adrp x0, \.L.+
> +** ldr q0, \[x0, #:lo12:\.L.+\]
> ** ret
> */
> uint32x4_t f6() {
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr121240.c
> b/gcc/testsuite/gcc.target/aarch64/pr121240.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..f04574d411c3fd4d6ac
> 2313fc27f2274e8926080
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr121240.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mcmodel=small" } */
> +
> +const double b[4] = {0.2435334343f, 0.2233535343f, 0.4232433f,
> 0.34343434f};
> +typedef double v2df __attribute__ ((vector_size (16)));
> +typedef double v2df __attribute__ ((vector_size (16)));
> +
> +v2df f (v2df c1, v2df c2)
> +{
> + v2df a1 = *(v2df *)&b[0];
> + v2df a2 = *(v2df *)&b[2];
> + return (a1 * c1) + (a2 * c2);
> +}
> +
> +/* { dg-final { scan-assembler-times "adrp" 1 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> b/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> index
> 274b0b39ac434d887b43a07c30fb41218bdf8768..ec9a74b8bdef426c5bd4
> 3e8a9247d53821fc7286 100644
> --- a/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> +++ b/gcc/testsuite/gcc.target/aarch64/vec-init-single-const.c
> @@ -46,8 +46,8 @@ int32x4_t f_s32(int32_t x)
>
> /*
> ** f_s64:
> -** adrp x[0-9]+, .LC[0-9]+
> -** ldr q0, \[x[0-9]+, #:lo12:.LC[0-9]+\]
> +** adrp x[0-9]+, .L.+
> +** ldr q0, \[x[0-9]+, #:lo12:.L.+\]
> ** ins v0\.d\[0\], x0
> ** ret
> */