aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-04-27 11:20:49 +0200
committerRichard Biener <rguenther@suse.de>2023-04-27 13:16:48 +0200
commit0403d2957929fa12bbd379e3839a8d0c2160576f (patch)
tree292cd7569bd557e4fd42de2e157a4e1ffadd5284 /gcc/gimplify.cc
parentd89e23f27215fcd822994fb2fad17fcd31eef5e1 (diff)
downloadgcc-0403d2957929fa12bbd379e3839a8d0c2160576f.zip
gcc-0403d2957929fa12bbd379e3839a8d0c2160576f.tar.gz
gcc-0403d2957929fa12bbd379e3839a8d0c2160576f.tar.bz2
Properly gimplify handled component chains on registers
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.
Diffstat (limited to 'gcc/gimplify.cc')
-rw-r--r--gcc/gimplify.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 5a83405..c38a962 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));