[gcc r12-4182] More .DEFERRED_INIT expansion rework

Richard Biener rguenth@gcc.gnu.org
Tue Oct 5 08:36:20 GMT 2021


https://gcc.gnu.org/g:604459a09585314841cdce4698893c656481691b

commit r12-4182-g604459a09585314841cdce4698893c656481691b
Author: Richard Biener <rguenther@suse.de>
Date:   Tue Oct 5 09:28:20 2021 +0200

    More .DEFERRED_INIT expansion rework
    
    This avoids looking at the type size and instead uses the size
    as passed to .DEFERRED_INIT to determine the size of the non-MEM
    to be initialized.  It also arranges for possibly poly-int
    inits to always use zero-initialization rather than not initializing
    and when we need to pun puns the LHS instead of the constant value.
    
    That correctly initializes the variable-size typed array in the
    testcase for PR102285 and the SVE vector in PR102587 where for
    the testcase I needed to add a SVE capable -march as to not
    ICE later.
    
    2021-10-05  Richard Biener  <rguenther@suse.de>
    
            PR middle-end/102587
            PR middle-end/102285
            * internal-fn.c (expand_DEFERRED_INIT): Fall back to
            zero-initialization as last resort, use the constant
            size as given by the DEFERRED_INIT argument to build
            the initializer.
    
            * gcc.target/aarch64/sve/pr102587-1.c: Add -march=armv8.3-a+sve.
            * gcc.target/aarch64/sve/pr102587-2.c: Likewise.

Diff:
---
 gcc/internal-fn.c                                 | 27 +++++++++++++----------
 gcc/testsuite/gcc.target/aarch64/sve/pr102587-1.c |  2 +-
 gcc/testsuite/gcc.target/aarch64/sve/pr102587-2.c |  2 +-
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 110145218b9..78db25bbac4 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3038,19 +3038,18 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
       /* Expand this memset call.  */
       expand_builtin_memset (m_call, NULL_RTX, TYPE_MODE (var_type));
     }
-  /* ???  Deal with poly-int sized registers.  */
-  else if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (var_type)))
+  else
     {
-      /* If this variable is in a register, use expand_assignment might
-	 generate better code.  */
-      tree init = build_zero_cst (var_type);
-      unsigned HOST_WIDE_INT total_bytes
-	= tree_to_uhwi (TYPE_SIZE_UNIT (var_type));
-
-      if (init_type == AUTO_INIT_PATTERN)
+      /* If this variable is in a register use expand_assignment.  */
+      tree init;
+      if (tree_fits_uhwi_p (var_size)
+	  && (init_type == AUTO_INIT_PATTERN
+	      || !is_gimple_reg_type (var_type)))
 	{
+	  unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
 	  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
-	  memset (buf, INIT_PATTERN_VALUE, total_bytes);
+	  memset (buf, (init_type == AUTO_INIT_PATTERN
+			? INIT_PATTERN_VALUE : 0), total_bytes);
 	  if (can_native_interpret_type_p (var_type))
 	    init = native_interpret_expr (var_type, buf, total_bytes);
 	  else
@@ -3058,10 +3057,14 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
 	      tree itype = build_nonstandard_integer_type
 			     (total_bytes * BITS_PER_UNIT, 1);
 	      wide_int w = wi::from_buffer (buf, total_bytes);
-	      init = build1 (VIEW_CONVERT_EXPR, var_type,
-			     wide_int_to_tree (itype, w));
+	      init = wide_int_to_tree (itype, w);
+	      /* Pun the LHS to make sure its type has constant size.  */
+	      lhs = build1 (VIEW_CONVERT_EXPR, itype, lhs);
 	    }
 	}
+      else
+	/* Use zero-init also for variable-length sizes.  */
+	init = build_zero_cst (var_type);
 
       expand_assignment (lhs, init, false);
     }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr102587-1.c b/gcc/testsuite/gcc.target/aarch64/sve/pr102587-1.c
index 2b9a68b0b59..af2ae59e5d4 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr102587-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr102587-1.c
@@ -1,4 +1,4 @@
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero" } */
+/* { dg-options "-march=armv8.3-a+sve -ftrivial-auto-var-init=zero" } */
 
 void foo() { __SVFloat64_t f64; }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr102587-2.c b/gcc/testsuite/gcc.target/aarch64/sve/pr102587-2.c
index 4cdb9056002..8c9d9908bac 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr102587-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr102587-2.c
@@ -1,4 +1,4 @@
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+/* { dg-options "-march=armv8.3-a+sve -ftrivial-auto-var-init=pattern" } */
 
 void foo() { __SVFloat64_t f64; }


More information about the Gcc-cvs mailing list