diff options
author | Richard Biener <rguenther@suse.de> | 2023-04-27 11:20:49 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-04-27 13:16:48 +0200 |
commit | 0403d2957929fa12bbd379e3839a8d0c2160576f (patch) | |
tree | 292cd7569bd557e4fd42de2e157a4e1ffadd5284 | |
parent | d89e23f27215fcd822994fb2fad17fcd31eef5e1 (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/gimplify.cc | 16 |
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)); |