On Wed, Feb 4, 2026 at 9:22 AM Andrew Pinski <[email protected]> wrote: > > Currently extract_component uses force_gimple_operand_gsi to emit > gimple including loads. The problem with that decls that have > DECL_EXPR_DECL set on it will change over to use the DECL_EXPR_DECL instead. > Normally this is ok except for nested functions where the original decl > is a PARAM_DECL, there is a copy from the param decl to the new frame based > location. > Well instead we should just create the gimple ourselves. > The only special case that needs to be handled is BIT_FIELD_REF and > a VCE of SSA_NAME. BIT_FIELD_REF was already handled specially > so we can just emit the load there. VCE of SSA_NAME on the other > hand needed some extra code. > > Note VCE of s SSA_NAME case could be optimized, I filed PR 123968 > for that. Since that is not a regression at this point and we are > now producing the same code as before. > > Bootstrapped and tested on x86_64-linux-gnu.
This part is OK. Bonus points for updating virtual SSA form on the go as followup, and remove the update_ssa requirement of the pass. Thanks, Richard. > PR middle-end/121661 > > gcc/ChangeLog: > > * tree-complex.cc (extract_component): Create gimple > assign statements directly rather than call force_gimple_operand_gsi. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/pr121661-1.c: New test. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/testsuite/gcc.dg/torture/pr121661-1.c | 21 +++++++++++ > gcc/tree-complex.cc | 46 +++++++++++++++++++---- > 2 files changed, 60 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr121661-1.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr121661-1.c > b/gcc/testsuite/gcc.dg/torture/pr121661-1.c > new file mode 100644 > index 00000000000..3bc2a8ebfb4 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr121661-1.c > @@ -0,0 +1,21 @@ > +/* { dg-do run } */ > +/* { dg-options "" } */ > +/* PR middle-end/121661 */ > + > +static void fun1(_Complex int val) > +{ > + __attribute__((unused)) > + void nfun() > + { > + if (__real__ val != 1) > + __builtin_abort(); > + } > + (void)&val; > + if (__real__ val != 1) > + __builtin_abort(); > +} > + > +int main(int argc, char* []) > +{ > + fun1(1); > +} > diff --git a/gcc/tree-complex.cc b/gcc/tree-complex.cc > index 7cd5aa6300f..59d9a5052c6 100644 > --- a/gcc/tree-complex.cc > +++ b/gcc/tree-complex.cc > @@ -652,28 +652,60 @@ extract_component (gimple_stmt_iterator *gsi, tree t, > bool imagpart_p, > if (imagpart_p) > TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2), > TYPE_SIZE (inner_type)); > + > if (gimple_p) > - t = force_gimple_operand_gsi (gsi, t, true, NULL, true, > - GSI_SAME_STMT); > + { > + tree new_lhs = make_ssa_name (inner_type); > + gimple *new_load = gimple_build_assign (new_lhs, t); > + gsi_insert_before (gsi, new_load, GSI_SAME_STMT); > + t = new_lhs; > + } > return t; > } > > + case VIEW_CONVERT_EXPR: > + /* Getting the real/imag parts of a VCE of a ssa-name requires > + to place the complex into a ssa name before getting the > + 2 parts. > + As `IMAGPART_EXPR<VIEW_CONVERT_EXPR<a_BN>>` is an invalid > + gimple. This will only show up when gimplifying it. > + Note this creates an extra copy. The call to > + force_gimple_operand_gsi would create one too. */ > + if (TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME) > + { > + gcc_assert (gimple_p); > + tree new_cplx = make_ssa_name (TREE_TYPE (t)); > + gimple *vce = gimple_build_assign (new_cplx, unshare_expr (t)); > + gsi_insert_before (gsi, vce, GSI_SAME_STMT); > + > + tree new_lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (t))); > + t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR), > + TREE_TYPE (TREE_TYPE (t)), new_cplx); > + gimple *new_ri = gimple_build_assign (new_lhs, t); > + gsi_insert_before (gsi, new_ri, GSI_SAME_STMT); > + t = new_lhs; > + return t; > + } > + /* FALLTHRU */ > case VAR_DECL: > case RESULT_DECL: > case PARM_DECL: > case COMPONENT_REF: > case ARRAY_REF: > - case VIEW_CONVERT_EXPR: > case MEM_REF: > { > tree inner_type = TREE_TYPE (TREE_TYPE (t)); > > - t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR), > - inner_type, unshare_expr (t)); > + t = fold_build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR), > + inner_type, unshare_expr (t)); > > if (gimple_p) > - t = force_gimple_operand_gsi (gsi, t, true, NULL, true, > - GSI_SAME_STMT); > + { > + tree new_lhs = make_ssa_name (inner_type); > + gimple *new_load = gimple_build_assign (new_lhs, t); > + gsi_insert_before (gsi, new_load, GSI_SAME_STMT); > + t = new_lhs; > + } > > return t; > } > -- > 2.43.0 >
