This is what I've just pushed. -- >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 | 6 ++-- gcc/testsuite/gfortran.dg/non_lvalue_1.f90 | 32 ++++++++++++++++++++++ 2 files changed, 35 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..f4416d9172c 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,7 @@ 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))) + (non_lvalue (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 +5767,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (conj (convert? (conj @0))) (if (tree_nop_conversion_p (TREE_TYPE (@0), type)) - (convert @0))) + (non_lvalue (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