From: Dhruv Chawla <[email protected]>

r17-4816-gb24418a2212866 gives a call whose result is discarded a placeholder
lhs using create_tmp_var, which gives a VAR_DECL. This ends up setting
ssa_renaming_needed and the subsequent fold passes do not set TODO_update_ssa,
so execute_todo ICEs. This is only set for register types and not for
aggregates, like svfloat32x2_t, which cannot be made via make_ssa_name
regardless. Thus, only generate the SSA name when is_gimple_reg_type is
true.

This needs the fold to run after SSA construction. In the testcase the second
operand is not yet a constant when intrinsics are first folded from
gimple-low, so the fold only succeeds once CCP has executed.

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla <[email protected]>

gcc/ChangeLog:

        PR target/127771
        * config/aarch64/aarch64-acle-builtins.cc: Include ssa.h.
        (gimple_folder::fold): Make an SSA name for the placeholder when
        is_gimple_reg_type and release it when unused.

gcc/testsuite/ChangeLog:

        PR target/127771
        * gcc.target/aarch64/sve/acle/general/pr127771.c: New test.
---
 gcc/config/aarch64/aarch64-acle-builtins.cc   | 37 ++++++++++++++++---
 .../aarch64/sve/acle/general/pr127771.c       | 21 +++++++++++
 2 files changed, 52 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr127771.c

diff --git a/gcc/config/aarch64/aarch64-acle-builtins.cc 
b/gcc/config/aarch64/aarch64-acle-builtins.cc
index 5abcc01b96bf..238570d9becd 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.cc
+++ b/gcc/config/aarch64/aarch64-acle-builtins.cc
@@ -46,6 +46,7 @@
 #include "gimple-fold.h"
 #include "langhooks.h"
 #include "stringpool.h"
+#include "ssa.h"
 #include "attribs.h"
 #include "value-range.h"
 #include "tree-ssanames.h"
@@ -3142,16 +3143,40 @@ gimple_folder::fold ()
   /* 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.  */
+  tree placeholder = NULL_TREE;
   if (!lhs && TREE_TYPE (gimple_call_fntype (call)) != void_type_node)
-    lhs = create_tmp_var (TREE_TYPE (gimple_call_fntype (call)));
+    {
+      tree type = TREE_TYPE (gimple_call_fntype (call));
+
+      /* PR target/127771: A register result has to be an SSA name as VAR_DECLs
+        created via create_tmp_var set ssa_renaming_needed and the fold passes
+        do not set TODO_update_ssa, so execute_todo ICEs.  Aggregates cannot be
+        SSA names at all, but they do not set that flag either, so a
+        declaration is both necessary and safe for them.  */
+      if (is_gimple_reg_type (type))
+       lhs = placeholder = make_ssa_name (type);
+      else
+       lhs = create_tmp_var (type);
+    }
 
   /* First try some simplifications that are common to many functions.  */
-  if (auto *call = redirect_pred_x ())
-    return call;
-  if (auto *call = fold_pfalse ())
-    return call;
+  gimple *stmt = redirect_pred_x ();
+  if (!stmt)
+    stmt = fold_pfalse ();
+  if (!stmt)
+    stmt = base->fold (*this);
+
+  /* Release a placeholder that nothing defines and nothing uses, because
+     gimple_build_assign does not set the definition until insertion and
+     convert_and_fold returns a different statement from the one it inserts.  
*/
+  if (placeholder && (!stmt || gimple_get_lhs (stmt) != placeholder))
+    {
+      gimple *def = SSA_NAME_DEF_STMT (placeholder);
+      if (has_zero_uses (placeholder) && (!def || gimple_nop_p (def)))
+       release_ssa_name (placeholder);
+    }
 
-  return base->fold (*this);
+  return stmt;
 }
 
 /* Force EXPR to be a GIMPLE value, putting it into a new variable if
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr127771.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr127771.c
new file mode 100644
index 000000000000..0a024ca4954f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr127771.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <arm_sve.h>
+
+/* PR target/127771  */
+
+void
+g (svbool_t p, svuint32_t a)
+{
+  svmul_x (p, a, svdup_u32 (1));
+}
+
+/* The placeholder for a discarded result cannot be an SSA name when the
+   return type is an aggregate.  */
+
+void
+h (svuint32_t a, svuint32_t b)
+{
+  svcreate2_u32 (a, b);
+}
-- 
2.43.0

Reply via email to