On Tue, Mar 11, 2025 at 12:13:13PM +0100, Richard Biener wrote:
> On Tue, 11 Mar 2025, Jakub Jelinek wrote:
>
> > On Tue, Mar 11, 2025 at 10:18:18AM +0100, Richard Biener wrote:
> > > I think the patch as-is is more robust, but still - ugh ... I wonder
> > > whether we can instead avoid introducing the COMPLEX_EXPR at all
> > > at -O0?
> >
> > Can we set DECL_NOT_GIMPLE_REG_P at -O0 during gimplification (where
> > we've already handled some uses/setters of it), at least when
> > gimplify_modify_expr_complex_part sees {REAL,IMAG}PART_EXPR on
> > {VAR,PARM,RESULT}_DECL?
>
> Yes, that should work for LHS __real / __imag.
Unfortunately it doesn't.
Although successfully bootstrapped on x86_64-linux and i686-linux,
it caused g++.dg/cpp1z/decomp2.C, g++.dg/torture/pr109262.C and
g++.dg/torture/pr88149.C regressions.
Minimal testcase is -O0:
void
foo (float x, float y)
{
__complex__ float z = x + y * 1.0fi;
__real__ z = 1.0f;
}
which ICEs with
pr88149.c: In function ‘foo’:
pr88149.c:2:1: error: non-register as LHS of binary operation
2 | foo (float x, float y)
| ^~~
z = COMPLEX_EXPR <_2, y.0>;
pr88149.c:2:1: internal compiler error: ‘verify_gimple’ failed
When the initialization is being gimplified, z is still
not DECL_NOT_GIMPLE_REG_P and so is_gimple_reg is true for it and
so it gimplifies it as
z = COMPLEX_EXPR <_2, y.0>;
later, instead of building
_3 = IMAGPART_EXPR <z>;
z = COMPLEX_EXPR <1.0e+0, _3>;
like before, the patch forces z to be not a gimple reg and uses
REALPART_EXPR <z> = 1.0e+0;
but it is too late, nothing fixes up the gimplification of the COMPLEX_EXPR
anymore.
So, I think we'd really need to do it the old way with adjusted naming
of the flag, so assume for all non-addressable
VAR_DECLs/PARM_DECLs/RESULT_DECLs with COMPLEX_TYPE if (!optimize) they
are DECL_NOT_GIMPLE_REG_P (perhaps with the exception of
get_internal_tmp_var), and at some point (what) if at all optimize that
away if the partial accesses aren't done.
Thoughts on this?
2025-03-11 Jakub Jelinek <[email protected]>
PR target/119120
* gimplify.cc (gimplify_modify_expr): Don't call
gimplify_modify_expr_complex_part for -O0, instead set
DECL_NOT_GIMPLE_REG_P on the {REAL,IMAG}PART_EXPR operand.
--- gcc/gimplify.cc.jj 2025-03-10 09:31:20.579772627 +0100
+++ gcc/gimplify.cc 2025-03-11 15:03:27.633636148 +0100
@@ -7237,7 +7237,15 @@ gimplify_modify_expr (tree *expr_p, gimp
if ((TREE_CODE (*to_p) == REALPART_EXPR
|| TREE_CODE (*to_p) == IMAGPART_EXPR)
&& is_gimple_reg (TREE_OPERAND (*to_p, 0)))
- return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
+ {
+ if (optimize)
+ return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
+ /* When not optimizing, instead set DECL_NOT_GIMPLE_REG_P on it and
+ keep using {REAL,IMAG}PART_EXPR on the partial initializations
+ in order to avoid copying around uninitialized parts. See
+ PR119120. */
+ DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (*to_p, 0)) = 1;
+ }
/* Try to alleviate the effects of the gimplification creating artificial
temporaries (see for example is_gimple_reg_rhs) on the debug info, but
Jakub