> On 15 Sep 2026, at 17:20, Karl Meakin <[email protected]> wrote:
>
> Don't bail out of folding intrinsics early if the result of the function
> call is unused. This assumed that function bases would always have an
> implementation of `expand` to generate RTL if the call was not folded
> away. This is not true of the NEON intrinsics, nearly all of which only
> have an implementation of `fold`.
>
> Instead of bailing out, compute the result and store it in a variable.
> If the result is unused, it will be removed by later optimization
> passes.
>
Ok, thanks.
Feel free to commit it independently of the rest of the series.
Kyrill
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-acle-builtins.cc (gimple_folder::fold):
> Don't bail out of folding early.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/neon/discarded_result.c: New test.
> ---
> gcc/config/aarch64/aarch64-acle-builtins.cc | 8 ++++----
> .../gcc.target/aarch64/neon/discarded_result.c | 16 ++++++++++++++++
> 2 files changed, 20 insertions(+), 4 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/discarded_result.c
>
> diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc
> b/gcc/config/aarch64/aarch64-acle-builtins.cc
> index a37b4bc1198..5a063fb46eb 100644
> --- a/gcc/config/aarch64/aarch64-acle-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
> @@ -3113,11 +3113,11 @@ gimple_folder::fold ()
> if (!TARGET_SIMD && !TARGET_SVE)
> return NULL;
>
> - /* Punt if the function has a return type and no result location is
> - provided. The attributes should allow target-independent code to
> - remove the calls if appropriate. */
> + /* Create a placeholder variable for the result.
> + This allows implementers of `fold` to assume `lhs` will never be null.
> + If the result is unused, it will be optimized away later. */
> if (!lhs && TREE_TYPE (gimple_call_fntype (call)) != void_type_node)
> - return NULL;
> + lhs = create_tmp_var (TREE_TYPE (gimple_call_fntype (call)));
>
> /* First try some simplifications that are common to many functions. */
> if (auto *call = redirect_pred_x ())
> diff --git a/gcc/testsuite/gcc.target/aarch64/neon/discarded_result.c
> b/gcc/testsuite/gcc.target/aarch64/neon/discarded_result.c
> new file mode 100644
> index 00000000000..183b162f2ee
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/neon/discarded_result.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +/* { dg-additional-options "-fno-trapping-math" } */
> +
> +#include "arm_neon_test.h"
> +
> +/* Assert that discarding the result of a NEON intrinsic does not cause a
> crash during folding. */
> +
> +/*
> +** foo:
> +** ret
> +*/
> +void foo(float32x2_t a, float32x2_t b)
> +{
> + vadd_f32 (a, b);
> +}
> --
> 2.51.0
>