On Sun, Jun 22, 2025 at 2:11 PM Mikael Morin <morin-mik...@orange.fr> wrote: > > From: Mikael Morin <mik...@gcc.gnu.org> > > Changes v1 -> v2: > - Also handle complex conjugate operator.
That's OK. > - Don't create the NON_LVALUE_EXPR if there is a type conversion between the > doubled operators. We're not doing that elsewhere so I'd rather not do it here either. Does it cause actual problems? > Regression tested on x86_64-linux. OK for master? > > -- 8< -- > > gcc/ChangeLog: > > * match.pd (`-(-X)`, `~(~X)`, `conj(conj(X))`): Add a > NON_LVALUE_EXPR wrapper to the simplification of doubled unary > operators NEGATE_EXPR, BIT_NOT_EXPR and CONJ_EXPR. > > gcc/testsuite/ChangeLog: > > * gfortran.dg/non_lvalue_1.f90: New test. > --- > gcc/match.pd | 10 +++++-- > gcc/testsuite/gfortran.dg/non_lvalue_1.f90 | 32 ++++++++++++++++++++++ > 2 files changed, 39 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gfortran.dg/non_lvalue_1.f90 > > diff --git a/gcc/match.pd b/gcc/match.pd > index 0f53c162fce..372d4657baa 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -2357,7 +2357,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > /* ~~x -> x */ > (simplify > (bit_not (bit_not @0)) > - @0) > + (non_lvalue @0)) > > /* zero_one_valued_p will match when a value is known to be either > 0 or 1 including constants 0 or 1. > @@ -4037,7 +4037,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (negate (nop_convert? (negate @1))) > (if (!TYPE_OVERFLOW_SANITIZED (type) > && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1))) > - (view_convert @1))) > + (if (GENERIC && type == TREE_TYPE (@1)) > + (non_lvalue @1) > + (view_convert @1)))) > > /* We can't reassociate floating-point unless -fassociative-math > or fixed-point plus or minus because of saturation to +-Inf. */ > @@ -5767,7 +5769,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (simplify > (conj (convert? (conj @0))) > (if (tree_nop_conversion_p (TREE_TYPE (@0), type)) > - (convert @0))) > + (if (GENERIC && type == TREE_TYPE (@0)) > + (non_lvalue @0) > + (convert @0)))) > > /* conj({x,y}) -> {x,-y} */ > (simplify > diff --git a/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 > b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 > new file mode 100644 > index 00000000000..61dad5a2ce1 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 > @@ -0,0 +1,32 @@ > +! { dg-do compile } > +! { dg-additional-options "-fdump-tree-original" } > +! > +! Check the generation of NON_LVALUE_EXPR expressions in cases where a unary > +! operator expression would simplify to a bare data reference. > + > +! A NON_LVALUE_EXPR is generated for a double negation that would simplify to > +! a bare data reference. > +function f1 (f1_arg1) > + integer, value :: f1_arg1 > + integer :: f1 > + f1 = -(-f1_arg1) > +end function > +! { dg-final { scan-tree-dump "__result_f1 = NON_LVALUE_EXPR <f1_arg1>;" > "original" } } > + > +! A NON_LVALUE_EXPR is generated for a double complement that would simplify > to > +! a bare data reference. > +function f2 (f2_arg1) > + integer, value :: f2_arg1 > + integer :: f2 > + f2 = not(not(f2_arg1)) > +end function > +! { dg-final { scan-tree-dump "__result_f2 = NON_LVALUE_EXPR <f2_arg1>;" > "original" } } > + > +! A NON_LVALUE_EXPR is generated for a double complex conjugate that would > +! simplify to a bare data reference. > +function f3 (f3_arg1) > + complex, value :: f3_arg1 > + complex :: f3 > + f3 = conjg(conjg(f3_arg1)) > +end function > +! { dg-final { scan-tree-dump "__result_f3 = NON_LVALUE_EXPR <f3_arg1>;" > "original" } } > -- > 2.47.2 >