]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Properly gimplify handled component chains on registers
authorRichard Biener <rguenther@suse.de>
Thu, 27 Apr 2023 09:20:49 +0000 (11:20 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 27 Apr 2023 11:16:48 +0000 (13:16 +0200)
When for example complex lowering wants to extract the imaginary
part of a complex variable for lowering a complex move we can
end up with it generating __imag <VIEW_CONVERT_EXPR <_22> > which
is valid GENERIC.  It then feeds that to the gimplifier via
force_gimple_operand but that fails to split up this chain
of handled components, generating invalid GIMPLE catched by
verification when PR109644 is fixed.

The following rectifies this by noting in gimplify_compound_lval
when the base object which we gimplify first ends up being a
register.

* gimplify.cc (gimplify_compound_lval): When the base
gimplified to a register make sure to split up chains
of operations.

gcc/gimplify.cc

index 5a8340504d044812d6885e79502e09459b35858b..c38a962dd0421c5db637f46a64030e02172c82dd 100644 (file)
@@ -3281,15 +3281,21 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   if (need_non_reg && (fallback & fb_rvalue))
     prepare_gimple_addressable (p, pre_p);
 
+
   /* Step 3: gimplify size expressions and the indices and operands of
-     ARRAY_REF.  During this loop we also remove any useless conversions.  */
+     ARRAY_REF.  During this loop we also remove any useless conversions.
+     If we operate on a register also make sure to properly gimplify
+     to individual operations.  */
 
+  bool reg_operations = is_gimple_reg (*p);
   for (; expr_stack.length () > 0; )
     {
       tree t = expr_stack.pop ();
 
       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
        {
+         gcc_assert (!reg_operations);
+
          /* Gimplify the low bound and element type size. */
          tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
                                is_gimple_reg, fb_rvalue);
@@ -3306,10 +3312,18 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        }
       else if (TREE_CODE (t) == COMPONENT_REF)
        {
+         gcc_assert (!reg_operations);
+
          tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
                                is_gimple_reg, fb_rvalue);
          ret = MIN (ret, tret);
        }
+      else if (reg_operations)
+       {
+         tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
+                               is_gimple_val, fb_rvalue);
+         ret = MIN (ret, tret);
+       }
 
       STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));