From: Richard Biener Date: Tue, 5 Oct 2021 07:28:20 +0000 (+0200) Subject: More .DEFERRED_INIT expansion rework X-Git-Tag: basepoints/gcc-13~4131 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=604459a09585314841cdce4698893c656481691b;p=thirdparty%2Fgcc.git 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 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 --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 110145218b94..78db25bbac42 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 2b9a68b0b59c..af2ae59e5d48 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 4cdb90560029..8c9d9908bac6 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; }