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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
You mean -fno-strict-aliasing?  I guess many options change the behavior that
it doesn't trigger anymore.
In the #c3 dump, I really don't see how aliasing could matter though, all are
MEM_REFs with addresses of particular automatic vars, there are no pointers
involved.

I've instrumented the compiler a little bit:
--- gcc/gimple-pretty-print.c.jj        2019-01-01 12:37:15.700998856 +0100
+++ gcc/gimple-pretty-print.c   2019-03-01 17:44:46.673862737 +0100
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "tree-dfa.h"

 #define INDENT(SPACE)                                                  \
   do { int i; for (i = 0; i < SPACE; i++) pp_space (buffer); } while (0)
@@ -575,6 +576,7 @@ dump_ternary_rhs (pretty_printer *buffer
     }
 }

+volatile bool assign_extra;

 /* Dump the gimple assignment GS.  BUFFER, SPC and FLAGS are as in
    pp_gimple_stmt_1.  */
@@ -634,6 +636,35 @@ dump_gimple_assign (pretty_printer *buff
         gcc_unreachable ();
       if (!(flags & TDF_RHS_ONLY))
        pp_semicolon (buffer);
+
+      if (assign_extra && gimple_num_ops (gs) == 2)
+       {
+         bool any = false;
+         for (int i = 0; i < 2; i++)
+           {
+             tree op = gimple_op (gs, i);
+             if (handled_component_p (op)
+                 || TREE_CODE (op) == MEM_REF
+                 || TREE_CODE (op) == TARGET_MEM_REF
+                 || DECL_P (op))
+               {
+                 poly_int64 off, size, max_size;
+                 bool dummy;
+                 get_ref_base_and_extent (op, &off, &size, &max_size, &dummy);
+                  if (!any)
+                   {
+                     pp_string (buffer, "//");
+                     any = true;
+                   }
+                 pp_string (buffer, i ? " rhs1 " : " lhs ");
+                 pp_wide_integer (buffer, off);
+                  pp_space (buffer);
+                 pp_wide_integer (buffer, size);
+                 pp_space (buffer);
+                 pp_wide_integer (buffer, max_size);
+               }
+           }
+       }
     }
 }

and at the start of late_intra_sra after set assign_extra = 1 debug_bb_n (2)
looks like below.
Extra comments added where the value 2 propagates through:

<bb 2> [local count: 1073741824]:
MEM[(struct  &)&merged1] ={v} {CLOBBER};// lhs 0 32 32
MEM[(struct  &)&merged1 + 4] ={v} {CLOBBER};// lhs 32 32 32
MEM[(struct  &)&merged1 + 8] ={v} {CLOBBER};// lhs 64 96 96
MEM[(struct  &)&merged1 + 8] ={v} {CLOBBER};// lhs 64 32 32
MEM[(struct  &)&merged1 + 12] ={v} {CLOBBER};// lhs 96 32 32
MEM[(struct  &)&merged1 + 16] ={v} {CLOBBER};// lhs 128 16 16
MEM[(struct  &)&D.9937] ={v} {CLOBBER};// lhs 0 128 128
D.9933 ={v} {CLOBBER};// lhs 0 96 96
MEM[(struct  &)&D.9936] ={v} {CLOBBER};// lhs 0 128 128
D.9940 ={v} {CLOBBER};// lhs 0 96 96
D.9941 ={v} {CLOBBER};// lhs 0 96 96
D.9942 ={v} {CLOBBER};// lhs 0 64 64
D.9936 ={v} {CLOBBER};// lhs 0 128 128
MEM[(struct  &)&n1] ={v} {CLOBBER};// lhs 0 128 128
D.9937 ={v} {CLOBBER};// lhs 0 128 128
n1 ={v} {CLOBBER};// lhs 0 128 128
MEM[(struct  &)&merged2] ={v} {CLOBBER};// lhs 0 32 32
MEM[(struct  &)&merged2 + 4] ={v} {CLOBBER};// lhs 32 32 32
MEM[(struct  &)&merged2 + 8] ={v} {CLOBBER};// lhs 64 96 96
MEM[(struct  &)&merged2 + 8] ={v} {CLOBBER};// lhs 64 32 32
MEM[(struct  &)&merged2 + 12] ={v} {CLOBBER};// lhs 96 32 32
MEM[(struct  &)&merged2 + 16] ={v} {CLOBBER};// lhs 128 16 16
MEM[(struct tuple &)&merged2 + 4].head.payload = 2;// lhs 32 32 32
// MEM[&merged2+4] == 2
MEM[(struct tuple &)&merged2 + 8].head.payload = 3;// lhs 64 32 32
D.9957.head = MEM[(const struct type_n &)&merged2 + 4];// lhs 0 32 32 rhs1 32
32 32
// MEM[&D.9957+0] == 2
MEM[(struct  &)&D.9959] ={v} {CLOBBER};// lhs 0 96 96
MEM[(struct tuple *)&D.9959].head = MEM[(const struct type_n &)&D.9957];// lhs
0 32 32 rhs1 0 32 32
// MEM[&D.9959+0] == 2
D.9957 ={v} {CLOBBER};// lhs 0 64 64
MEM[(struct tuple *)&D.9959 + 4B] = 4;// lhs 32 32 32
D.9960 = D.9959;// lhs 0 96 96 rhs1 0 96 96
// MEM[&D.9960+0] == 2
MEM[(struct  &)&D.9953] ={v} {CLOBBER};// lhs 0 128 128
D.9953.head = MEM[(const struct type_n &)&merged2 + 8];// lhs 0 32 32 rhs1 64
32 32
D.9953.tail = MEM[(const struct tuple &)&D.9960];// lhs 32 96 96 rhs1 0 96 96
// MEM[&D.9953+4] == 2
D.9960 ={v} {CLOBBER};// lhs 0 96 96
D.9959 ={v} {CLOBBER};// lhs 0 96 96
D.9952 = D.9953;// lhs 0 128 128 rhs1 0 128 128
// MEM[&D.9952+4] == 2
MEM[(struct  &)&D.9944] ={v} {CLOBBER};// lhs 0 160 160
MEM[(struct tuple *)&D.9944].tail = MEM[(const struct tuple &)&D.9952];// lhs
32 128 128 rhs1 0 128 128
// MEM[&D.9944+8] == 2
D.9952 ={v} {CLOBBER};// lhs 0 128 128
D.9953 ={v} {CLOBBER};// lhs 0 128 128
D.9954 ={v} {CLOBBER};// lhs 0 64 64
D.9947 = MEM[(const struct tuple &)&D.9944 + 8];// lhs 0 96 96 rhs1 64 96 96
// MEM[&D.9947+0] == 2
MEM[(struct tuple *)&D.9948].tail = MEM[(const struct tuple &)&D.9947];// lhs
32 96 96 rhs1 0 96 96
// MEM[&D.9948+4] == 2
SR.150_36 = MEM[(const struct tuple &)&D.9947 + 4];// rhs1 32 32 32
D.9947 ={v} {CLOBBER};// lhs 0 96 96
MEM[(struct  &)&D.9949] ={v} {CLOBBER};// lhs 0 96 96
D.9949.head = MEM[(const struct type_n &)&D.9948 + 4];// lhs 0 32 32 rhs1 32 32
32
// MEM[&D.9949+0] == 2
MEM[(struct  &)&n1] ={v} {CLOBBER};// lhs 0 128 128
MEM[(const struct tuple &)&D.9949 + 4] = SR.150_36;// lhs 32 32 32
n1.tail = MEM[(const struct tuple &)&D.9949];// lhs 32 96 96 rhs1 0 96 96
// MEM[&n1+4] == 2
D.9949 ={v} {CLOBBER};// lhs 0 96 96
D.9948 ={v} {CLOBBER};// lhs 0 128 128
D.9944 ={v} {CLOBBER};// lhs 0 160 160
_2 = n1.tail.head.payload;// rhs1 32 32 32
// _2 == 2
if (_2 != 2)
  goto <bb 3>; [0.00%]
else
  goto <bb 4>; [100.00%]

Thus, I believe the IL is correct at least of the 12 step propagation of value
2 down to _2 before late sra in main.  And that is all the testcase cares
about.

Reply via email to