Properly gimplify handled component chains on registers

Message ID 20230427111827.C411F3858425@sourceware.org
State Unresolved
Headers
Series Properly gimplify handled component chains on registers |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Richard Biener April 27, 2023, 11:17 a.m. UTC
  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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	* gimplify.cc (gimplify_compound_lval): When the base
	gimplified to a register make sure to split up chains
	of operations.
---
 gcc/gimplify.cc | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
  

Patch

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index b0bdd1b46cd..9755f79fb2d 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -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));