On 15/09/2026 17:19, Kyrylo Tkachov wrote:

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

Thanks, merged

Reply via email to