Le 23/06/2025 à 09:17, Richard Biener a écrit :
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?

No, I was not too sure about the conversion case, so tried to be conservative.
Thanks for the review, I'll drop that part.

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


Reply via email to