This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/69553] [6 Regression] Optimizations O1/O2 makes std::array value incorrect when passed to function


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69553

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the issue is that

&MEM[(const struct B[2] &)p1_2(D)][1]

and

&MEM[(const int[2] &)p1_2(D)][1]

are considered equal even though we have int[] vs. B[] and thus different
element sizes and different offsets (but same array indices) here.

For COMPONENT_REFs we compare the FIELD_DECL but for ARRAY_REFs and also
for IMAGPART_EXPR we fail to consider the element size.

Not that comparing TYPE_PRECISION on MEM_REFs of ARRAY_TYPE makes any sense,
or TYPE_UNSIGNED.

So the old code had bugs as well here (consider array types with different
low bound).

Index: fold-const.c
===================================================================
--- fold-const.c        (revision 233447)
+++ fold-const.c        (working copy)
@@ -3008,8 +3008,15 @@ operand_equal_p (const_tree arg0, const_
          flags &= ~OEP_ADDRESS_OF;
          return OP_SAME (0);

-       case REALPART_EXPR:
        case IMAGPART_EXPR:
+         /* Require the same offset.  */
+         if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
+                               TYPE_SIZE (TREE_TYPE (arg1)),
+                               flags & ~OEP_ADDRESS_OF)))
+           return 0;
+
+       /* Fallthru.  */
+       case REALPART_EXPR:
        case VIEW_CONVERT_EXPR:
          return OP_SAME (0);

@@ -3049,17 +3056,24 @@ operand_equal_p (const_tree arg0, const_

        case ARRAY_REF:
        case ARRAY_RANGE_REF:
-         /* Operands 2 and 3 may be null.
-            Compare the array index by value if it is constant first as we
-            may have different types but same value here.  */
          if (!OP_SAME (0))
            return 0;
          flags &= ~OEP_ADDRESS_OF;
+         /* Compare the array index by value if it is constant first as we
+            may have different types but same value here.
+            Compare low bound and element size as with OEP_ADDRESS_OF
+            we have to account for the offset of the ref.  */
          return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
                                       TREE_OPERAND (arg1, 1))
                   || OP_SAME (1))
-                 && OP_SAME_WITH_NULL (2)
-                 && OP_SAME_WITH_NULL (3));
+                 && operand_equal_p (array_ref_low_bound
+                                       (CONST_CAST_TREE (arg0)),
+                                     array_ref_low_bound
+                                       (CONST_CAST_TREE (arg1)), flags)
+                 && operand_equal_p (array_ref_element_size
+                                       (CONST_CAST_TREE (arg0)),
+                                     array_ref_element_size
+                                       (CONST_CAST_TREE (arg1)), flags));

        case COMPONENT_REF:
          /* Handle operand 2 the same as for ARRAY_REF.  Operand 0

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]