https://gcc.gnu.org/g:00d074b5fb8a53d59f80a0c9bc36c038d3c11cd8
commit 00d074b5fb8a53d59f80a0c9bc36c038d3c11cd8 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Thu Jul 4 12:59:34 2024 +0200 match: Simplify doubled not, negate and conjugate operators to a non_lvalue Changes v1 -> v2: - Also handle complex conjugate operator. - Don't create the NON_LVALUE_EXPR if there is a type conversion between the doubled operators. 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. Diff: --- gcc/match.pd | 10 +++++++--- gcc/testsuite/gfortran.dg/non_lvalue_1.f90 | 32 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 0f53c162fce3..372d4657baac 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 000000000000..61dad5a2ce1b --- /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" } }