]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/103271 - avoid VLA init of register
authorRichard Biener <rguenther@suse.de>
Thu, 2 Dec 2021 11:23:22 +0000 (12:23 +0100)
committerRichard Biener <rguenther@suse.de>
Thu, 2 Dec 2021 12:35:19 +0000 (13:35 +0100)
This avoids using VLA types to initalize a register with
-ftrivial-auto-var-init in some cases.

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

index 6ac3460d538be614dde529d389cde4e88704023b..08f94b7a17abe619c937b979c41aa6dda5fa0d93 100644 (file)
@@ -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)