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.
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