Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2017-10-24  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/82697
        * tree-ssa-phiopt.c (cond_store_replacement): Use alias-set
        zero for conditional load and unconditional store.

        * gcc.dg/torture/pr82697.c: New testcase.

Index: gcc/tree-ssa-phiopt.c
===================================================================
--- gcc/tree-ssa-phiopt.c       (revision 254036)
+++ gcc/tree-ssa-phiopt.c       (working copy)
@@ -1912,9 +1912,24 @@ cond_store_replacement (basic_block midd
   gsi_remove (&gsi, true);
   release_defs (assign);
 
+  /* Make both store and load use alias-set zero as we have to
+     deal with the case of the store being a conditional change
+     of the dynamic type.  */
+  lhs = unshare_expr (lhs);
+  tree *basep = &lhs;
+  while (handled_component_p (*basep))
+    basep = &TREE_OPERAND (*basep, 0);
+  if (TREE_CODE (*basep) == MEM_REF
+      || TREE_CODE (*basep) == TARGET_MEM_REF)
+    TREE_OPERAND (*basep, 1)
+      = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
+  else
+    *basep = build2 (MEM_REF, TREE_TYPE (*basep),
+                    build_fold_addr_expr (*basep),
+                    build_zero_cst (ptr_type_node));
+
   /* 2) Insert a load from the memory of the store to the temporary
         on the edge which did not contain the store.  */
-  lhs = unshare_expr (lhs);
   name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
   new_stmt = gimple_build_assign (name, lhs);
   gimple_set_location (new_stmt, locus);
Index: gcc/testsuite/gcc.dg/torture/pr82697.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr82697.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr82697.c      (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+__attribute__((noinline,noclone))
+void test(int *pi, long *pl, int f)
+{
+  *pl = 0;
+
+  *pi = 1;
+
+  if (f)
+    *pl = 2;
+}
+
+int main()
+{
+  void *p = __builtin_malloc(sizeof (long));
+
+  test(p, p, 0);
+
+  if (*(int *)p != 1)
+    __builtin_abort ();
+  return 0;
+}

Reply via email to