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
>

Reply via email to