middle-end/103271 - avoid VLA init of register

Message ID 6r68q34-s4n8-4912-s2r-23705o929651@fhfr.qr
State Committed
Commit 06b8cdc8d7339ac44802044ef148dd86874333d8
Headers
Series middle-end/103271 - avoid VLA init of register |

Commit Message

Richard Biener Dec. 2, 2021, 12:35 p.m. UTC
  This avoids using VLA types to initalize a register with
-ftrivial-auto-var-init in some cases.

Bootstrapped and tested on x86_64-unknown-linux-gnu, also tested on
the case riscv ICEd on.

Pushed.

2021-12-02  Richard Biener  <rguenther@suse.de>

	PR middle-end/103271
	* internal-fn.c (expand_DEFERRED_INIT): When the base
	of the LHS is a decl with matching constant size use
	that as the initialization target instead of an
	eventual VLA typed one.
---
 gcc/internal-fn.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
  

Patch

diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 6ac3460d538..08f94b7a17a 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3050,6 +3050,23 @@  expand_DEFERRED_INIT (internal_fn, gcall *stmt)
 	lhs_base = TREE_OPERAND (lhs_base, 0);
       reg_lhs = (mem_ref_refers_to_non_mem_p (lhs_base)
 		 || non_mem_decl_p (lhs_base));
+      /* If this expands to a register and the underlying decl is wrapped in
+	 a MEM_REF that just serves as an access type change expose the decl
+	 if it is of correct size.  This avoids a situation as in PR103271
+	 if the target does not support a direct move to the registers mode.  */
+      if (reg_lhs
+	  && TREE_CODE (lhs_base) == MEM_REF
+	  && TREE_CODE (TREE_OPERAND (lhs_base, 0)) == ADDR_EXPR
+	  && DECL_P (TREE_OPERAND (TREE_OPERAND (lhs_base, 0), 0))
+	  && integer_zerop (TREE_OPERAND (lhs_base, 1))
+	  && tree_fits_uhwi_p (var_size)
+	  && tree_int_cst_equal
+	       (var_size,
+		DECL_SIZE_UNIT (TREE_OPERAND (TREE_OPERAND (lhs_base, 0), 0))))
+	{
+	  lhs = TREE_OPERAND (TREE_OPERAND (lhs_base, 0), 0);
+	  var_type = TREE_TYPE (lhs);
+	}
     }
 
   if (!reg_lhs)