re PR tree-optimization/82291 (wrong code at -O3 on x86_64-linux-gnu)
authorRichard Biener <rguenther@suse.de>
Fri, 22 Sep 2017 12:00:55 +0000 (12:00 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 22 Sep 2017 12:00:55 +0000 (12:00 +0000)
2017-09-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/82291
* tree-if-conv.c (predicate_mem_writes): Make sure to
remove writes in blocks predicated with false.

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

From-SVN: r253093

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr82291.c [new file with mode: 0644]
gcc/tree-if-conv.c

index aa55e18557fd32c534c8adb9f3def4036f2b0ddd..5b9217c4b0a5f435716682cdc8596b99bb09a665 100644 (file)
@@ -1,3 +1,9 @@
+2017-09-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/82291
+       * tree-if-conv.c (predicate_mem_writes): Make sure to
+       remove writes in blocks predicated with false.
+
 2017-09-22  Richard Biener  <rguenther@suse.de>
 
        * sese.c: Include cfganal.h.
index 6f25855cdb1289ee73c1951f9eda8c89634d80aa..1c2776af002eefc2320c5d16e96e63dfca26e689 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/82291
+       * gcc.dg/torture/pr82291.c: New testcase.
+
 2017-09-22  Sergey Shalnov  <sergey.shalnov@intel.com>
 
         * gcc.target/i386/avx512f-constant-set.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr82291.c b/gcc/testsuite/gcc.dg/torture/pr82291.c
new file mode 100644 (file)
index 0000000..daa1665
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+int a, c, d, *h;
+unsigned b;
+
+int *fn1 ()
+{ 
+  int *f[3], g = 0;
+  for (; g < 3; g++)
+    f[g] = &a;
+  if (--b > a)
+    { 
+      if (a > b)
+       d++;
+      return f[0];
+    }
+}
+
+void fn2 ()
+{ 
+  for (; c >= 0; --c)
+    { 
+      int j[] = { 0, 0, 0, 0, 0 };
+      int *k = fn1 ();
+      if (!k)
+       __builtin_abort ();
+      h = &j[4];
+    }
+}
+
+int main ()
+{ 
+  fn2 ();
+  if (d != 0)
+    __builtin_abort ();
+  return 0;
+}
index 968d93cf86bf07e635e99b307a2e44ac4ba84077..e2fce3c114a55e418db4e26fea230b5dcdb2cd78 100644 (file)
@@ -2197,7 +2197,7 @@ predicate_mem_writes (loop_p loop)
       gimple *stmt;
       int index;
 
-      if (is_true_predicate (cond) || is_false_predicate (cond))
+      if (is_true_predicate (cond))
        continue;
 
       swap = false;
@@ -2210,97 +2210,107 @@ predicate_mem_writes (loop_p loop)
       vect_sizes.truncate (0);
       vect_masks.truncate (0);
 
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-       if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
-         continue;
-       else if (gimple_plf (stmt, GF_PLF_2))
-         {
-           tree lhs = gimple_assign_lhs (stmt);
-           tree rhs = gimple_assign_rhs1 (stmt);
-           tree ref, addr, ptr, mask;
-           gcall *new_stmt;
-           gimple_seq stmts = NULL;
-           int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
-           ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
-           mark_addressable (ref);
-           addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
-                                            true, NULL_TREE, true,
-                                            GSI_SAME_STMT);
-           if (!vect_sizes.is_empty ()
-               && (index = mask_exists (bitsize, vect_sizes)) != -1)
-             /* Use created mask.  */
-             mask = vect_masks[index];
-           else
-             {
-               if (COMPARISON_CLASS_P (cond))
-                 mask = gimple_build (&stmts, TREE_CODE (cond),
-                                      boolean_type_node,
-                                      TREE_OPERAND (cond, 0),
-                                      TREE_OPERAND (cond, 1));
-               else
-                 {
-                   gcc_assert (TREE_CODE (cond) == SSA_NAME);
-                   mask = cond;
-                 }
-
-               if (swap)
-                 {
-                   tree true_val
-                     = constant_boolean_node (true, TREE_TYPE (mask));
-                   mask = gimple_build (&stmts, BIT_XOR_EXPR,
-                                        TREE_TYPE (mask), mask, true_val);
-                 }
-               gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
-
-               mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi);
-               /* Save mask and its size for further use.  */
-               vect_sizes.safe_push (bitsize);
-               vect_masks.safe_push (mask);
-             }
-           ptr = build_int_cst (reference_alias_ptr_type (ref),
-                                get_object_alignment (ref));
-           /* Copy points-to info if possible.  */
-           if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
-             copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
-                            ref);
-           if (TREE_CODE (lhs) == SSA_NAME)
-             {
-               new_stmt
-                 = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
-                                               ptr, mask);
-               gimple_call_set_lhs (new_stmt, lhs);
-               gimple_set_vuse (new_stmt, gimple_vuse (stmt));
-             }
-           else
-             {
-               new_stmt
-                 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+       {
+         if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
+           ;
+         else if (is_false_predicate (cond))
+           {
+             unlink_stmt_vdef (stmt);
+             gsi_remove (&gsi, true);
+             release_defs (stmt);
+             continue;
+           }
+         else if (gimple_plf (stmt, GF_PLF_2))
+           {
+             tree lhs = gimple_assign_lhs (stmt);
+             tree rhs = gimple_assign_rhs1 (stmt);
+             tree ref, addr, ptr, mask;
+             gcall *new_stmt;
+             gimple_seq stmts = NULL;
+             int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
+             ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
+             mark_addressable (ref);
+             addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
+                                              true, NULL_TREE, true,
+                                              GSI_SAME_STMT);
+             if (!vect_sizes.is_empty ()
+                 && (index = mask_exists (bitsize, vect_sizes)) != -1)
+               /* Use created mask.  */
+               mask = vect_masks[index];
+             else
+               {
+                 if (COMPARISON_CLASS_P (cond))
+                   mask = gimple_build (&stmts, TREE_CODE (cond),
+                                        boolean_type_node,
+                                        TREE_OPERAND (cond, 0),
+                                        TREE_OPERAND (cond, 1));
+                 else
+                   {
+                     gcc_assert (TREE_CODE (cond) == SSA_NAME);
+                     mask = cond;
+                   }
+
+                 if (swap)
+                   {
+                     tree true_val
+                       = constant_boolean_node (true, TREE_TYPE (mask));
+                     mask = gimple_build (&stmts, BIT_XOR_EXPR,
+                                          TREE_TYPE (mask), mask, true_val);
+                   }
+                 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
+
+                 mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi);
+                 /* Save mask and its size for further use.  */
+                 vect_sizes.safe_push (bitsize);
+                 vect_masks.safe_push (mask);
+               }
+             ptr = build_int_cst (reference_alias_ptr_type (ref),
+                                  get_object_alignment (ref));
+             /* Copy points-to info if possible.  */
+             if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
+               copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
+                              ref);
+             if (TREE_CODE (lhs) == SSA_NAME)
+               {
+                 new_stmt
+                   = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
+                                                 ptr, mask);
+                 gimple_call_set_lhs (new_stmt, lhs);
+                 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+               }
+             else
+               {
+                 new_stmt
+                   = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
                                                  mask, rhs);
-               gimple_set_vuse (new_stmt, gimple_vuse (stmt));
-               gimple_set_vdef (new_stmt, gimple_vdef (stmt));
-               SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
-             }
-           gimple_call_set_nothrow (new_stmt, true);
+                 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+                 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+                 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
+               }
+             gimple_call_set_nothrow (new_stmt, true);
 
-           gsi_replace (&gsi, new_stmt, true);
-         }
-       else if (gimple_vdef (stmt))
-         {
-           tree lhs = gimple_assign_lhs (stmt);
-           tree rhs = gimple_assign_rhs1 (stmt);
-           tree type = TREE_TYPE (lhs);
-
-           lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
-           rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
-           if (swap)
-             std::swap (lhs, rhs);
-           cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
-                                              is_gimple_condexpr, NULL_TREE,
-                                              true, GSI_SAME_STMT);
-           rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
-           gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
-           update_stmt (stmt);
-         }
+             gsi_replace (&gsi, new_stmt, true);
+           }
+         else if (gimple_vdef (stmt))
+           {
+             tree lhs = gimple_assign_lhs (stmt);
+             tree rhs = gimple_assign_rhs1 (stmt);
+             tree type = TREE_TYPE (lhs);
+
+             lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
+             rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
+             if (swap)
+               std::swap (lhs, rhs);
+             cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
+                                                is_gimple_condexpr, NULL_TREE,
+                                                true, GSI_SAME_STMT);
+             rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
+             gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
+             update_stmt (stmt);
+           }
+         gsi_next (&gsi);
+       }
     }
 }