tree-outof-ssa.h (ssaexpand): Add partitions_for_undefined_values.
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 8 Oct 2017 21:13:52 +0000 (21:13 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 8 Oct 2017 21:13:52 +0000 (21:13 +0000)
* tree-outof-ssa.h (ssaexpand): Add partitions_for_undefined_values.
(always_initialized_rtx_for_ssa_name_p): New predicate.
* tree-outof-ssa.c (remove_ssa_form): Initialize new field of SA.
(finish_out_of_ssa): Free new field of SA.
* tree-ssa-coalesce.h (get_undefined_value_partitions): Declare.
* tree-ssa-coalesce.c: Include tree-ssa.h.
(get_parm_default_def_partitions): Remove extern keyword.
(get_undefined_value_partitions): New function.
* expr.c (expand_expr_real_1) <expand_decl_rtl>: For a SSA_NAME, do
not set SUBREG_PROMOTED_VAR_P on the sub-register if it may contain
uninitialized bits.
* loop-iv.c (iv_get_reaching_def): Disqualify all subregs.

From-SVN: r253530

gcc/ChangeLog
gcc/expr.c
gcc/loop-iv.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20171008-1.c [new file with mode: 0644]
gcc/tree-outof-ssa.c
gcc/tree-outof-ssa.h
gcc/tree-ssa-coalesce.c
gcc/tree-ssa-coalesce.h

index 96acd2be63908da285b9fea1c0f3cd846ae4bfec..baf6a6d96bd1184587a831e6e633b797c5b323a1 100644 (file)
@@ -1,3 +1,18 @@
+2017-10-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-outof-ssa.h (ssaexpand): Add partitions_for_undefined_values.
+       (always_initialized_rtx_for_ssa_name_p): New predicate.
+       * tree-outof-ssa.c (remove_ssa_form): Initialize new field of SA.
+       (finish_out_of_ssa): Free new field of SA.
+       * tree-ssa-coalesce.h (get_undefined_value_partitions): Declare.
+       * tree-ssa-coalesce.c: Include tree-ssa.h.
+       (get_parm_default_def_partitions): Remove extern keyword.
+       (get_undefined_value_partitions): New function.
+       * expr.c (expand_expr_real_1) <expand_decl_rtl>: For a SSA_NAME, do
+       not set SUBREG_PROMOTED_VAR_P on the sub-register if it may contain
+       uninitialized bits.
+       * loop-iv.c (iv_get_reaching_def): Disqualify all subregs.
+
 2017-10-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        * builtins.def (BUILT_IN_SETJMP): Revert latest change.
index 2f8432d92ccac17c0a548faf4a16eff0656cef1b..134ee731c294e8febdc85b033d4d50ad2cf98827 100644 (file)
@@ -9909,24 +9909,43 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
          && GET_MODE (decl_rtl) != dmode)
        {
          machine_mode pmode;
+         bool always_initialized_rtx;
 
          /* Get the signedness to be used for this variable.  Ensure we get
             the same mode we got when the variable was declared.  */
          if (code != SSA_NAME)
-           pmode = promote_decl_mode (exp, &unsignedp);
+           {
+             pmode = promote_decl_mode (exp, &unsignedp);
+             always_initialized_rtx = true;
+           }
          else if ((g = SSA_NAME_DEF_STMT (ssa_name))
                   && gimple_code (g) == GIMPLE_CALL
                   && !gimple_call_internal_p (g))
-           pmode = promote_function_mode (type, mode, &unsignedp,
-                                          gimple_call_fntype (g),
-                                          2);
+           {
+             pmode = promote_function_mode (type, mode, &unsignedp,
+                                           gimple_call_fntype (g), 2);
+             always_initialized_rtx
+               = always_initialized_rtx_for_ssa_name_p (ssa_name);
+           }
          else
-           pmode = promote_ssa_mode (ssa_name, &unsignedp);
+           {
+             pmode = promote_ssa_mode (ssa_name, &unsignedp);
+             always_initialized_rtx
+               = always_initialized_rtx_for_ssa_name_p (ssa_name);
+           }
+
          gcc_assert (GET_MODE (decl_rtl) == pmode);
 
          temp = gen_lowpart_SUBREG (mode, decl_rtl);
-         SUBREG_PROMOTED_VAR_P (temp) = 1;
-         SUBREG_PROMOTED_SET (temp, unsignedp);
+
+         /* We cannot assume anything about an existing extension if the
+            register may contain uninitialized bits.  */
+         if (always_initialized_rtx)
+           {
+             SUBREG_PROMOTED_VAR_P (temp) = 1;
+             SUBREG_PROMOTED_SET (temp, unsignedp);
+           }
+
          return temp;
        }
 
index 1d0c66f2b2ffca0cd96689216dfd00ec91303ff3..45e822980ff408a966fc3e48e6b800b492dd1fc1 100644 (file)
@@ -353,7 +353,7 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def)
   adef = DF_REF_CHAIN (use)->ref;
 
   /* We do not handle setting only part of the register.  */
-  if (DF_REF_FLAGS (adef) & DF_REF_READ_WRITE)
+  if (DF_REF_FLAGS (adef) & (DF_REF_READ_WRITE | DF_REF_SUBREG))
     return GRD_INVALID;
 
   def_insn = DF_REF_INSN (adef);
index e7045e8cba8d4801614e602570891734e4deb49d..c2a658c3dcf6aef104dab981c44d4be4b942ba2b 100644 (file)
@@ -1,3 +1,7 @@
+2017-10-08  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20171008-1.c: New test.
+
 2017-10-03  Jeff Law  <law@redhat.com>
 
        * gcc.dg/stack-check-5.c: Skip with -fstack-protector.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20171008-1.c b/gcc/testsuite/gcc.c-torture/execute/20171008-1.c
new file mode 100644 (file)
index 0000000..cde807a
--- /dev/null
@@ -0,0 +1,38 @@
+struct S { char c1, c2, c3, c4; } __attribute__((aligned(4)));
+
+static char bar (char **p) __attribute__((noclone, noinline));
+static struct S foo (void) __attribute__((noclone, noinline));
+
+int i;
+
+static char
+bar (char **p)
+{
+  i = 1;
+  return 0;
+}
+
+static struct S
+foo (void)
+{
+  struct S ret;
+  char r, s, c1, c2;
+  char *p = &r;
+
+  s = bar (&p);
+  if (s)
+    c2 = *p;
+  c1 = 0;
+
+  ret.c1 = c1;
+  ret.c2 = c2;
+  return ret;
+}
+
+int main (void)
+{
+  struct S s = foo ();
+  if (s.c1 != 0)
+    __builtin_abort ();
+  return 0;
+}
index 0ce6c155bd32d9228985028e72720bc17a4a6f28..6327c07c68bb6b4dda416223ab5f578adebb7762 100644 (file)
@@ -969,6 +969,7 @@ remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
   sa->map = map;
   sa->values = values;
   sa->partitions_for_parm_default_defs = get_parm_default_def_partitions (map);
+  sa->partitions_for_undefined_values = get_undefined_value_partitions (map);
 }
 
 
@@ -1144,6 +1145,7 @@ finish_out_of_ssa (struct ssaexpand *sa)
     BITMAP_FREE (sa->values);
   delete_var_map (sa->map);
   BITMAP_FREE (sa->partitions_for_parm_default_defs);
+  BITMAP_FREE (sa->partitions_for_undefined_values);
   memset (sa, 0, sizeof *sa);
 }
 
index e751a26f84868c6b6d358afdfb4813d712bdb367..1220b6256ca2052caff234540293139d0922baac 100644 (file)
@@ -42,6 +42,10 @@ struct ssaexpand
   /* If partition I contains an SSA name that has a default def for a
      parameter, bit I will be set in this bitmap.  */
   bitmap partitions_for_parm_default_defs;
+
+  /* If partition I contains an SSA name that has an undefined value,
+     bit I will be set in this bitmap.  */
+  bitmap partitions_for_undefined_values;
 };
 
 /* This is the singleton described above.  */
@@ -70,6 +74,18 @@ get_gimple_for_ssa_name (tree exp)
   return NULL;
 }
 
+/* Return whether the RTX expression representing the storage of the outof-SSA
+   partition that the SSA name EXP is a member of is always initialized.  */
+static inline bool
+always_initialized_rtx_for_ssa_name_p (tree exp)
+{
+  int p = partition_find (SA.map->var_partition, SSA_NAME_VERSION (exp));
+  if (SA.map->partition_to_view)
+    p = SA.map->partition_to_view[p];
+  gcc_assert (p != NO_PARTITION);
+  return !bitmap_bit_p (SA.partitions_for_undefined_values, p);
+}
+
 extern bool ssa_is_replaceable_p (gimple *stmt);
 extern void finish_out_of_ssa (struct ssaexpand *sa);
 extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa);
index e166314ed4d3d0b9a90e279c0a21a8c22b75a5a4..3938f064f67c6dace3461afb4a2c24fea6db1303 100644 (file)
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "memmodel.h"
 #include "tm_p.h"
 #include "ssa.h"
+#include "tree-ssa.h"
 #include "tree-pretty-print.h"
 #include "diagnostic-core.h"
 #include "dumpfile.h"
@@ -1923,7 +1924,7 @@ set_parm_default_def_partition (tree var, void *arg_)
 /* Allocate and return a bitmap that has a bit set for each partition
    that contains a default def for a parameter.  */
 
-extern bitmap
+bitmap
 get_parm_default_def_partitions (var_map map)
 {
   bitmap parm_default_def_parts = BITMAP_ALLOC (NULL);
@@ -1935,3 +1936,28 @@ get_parm_default_def_partitions (var_map map)
 
   return parm_default_def_parts;
 }
+
+/* Allocate and return a bitmap that has a bit set for each partition
+   that contains an undefined value.  */
+
+bitmap
+get_undefined_value_partitions (var_map map)
+{
+  bitmap undefined_value_parts = BITMAP_ALLOC (NULL);
+
+  for (unsigned int i = 1; i < num_ssa_names; i++)
+    {
+      tree var = ssa_name (i);
+      if (var
+         && !virtual_operand_p (var)
+         && !has_zero_uses (var)
+         && ssa_undefined_value_p (var))
+       {
+         const int p = var_to_partition (map, var);
+         if (p != NO_PARTITION)
+           bitmap_set_bit (undefined_value_parts, p);
+       }
+    }
+
+  return undefined_value_parts;
+}
index 9eebdddf917c28699e9f6d0d88a09c59783fa644..98e61c5d34a256acd751ce8efbdbda072c348af1 100644 (file)
@@ -23,5 +23,6 @@ along with GCC; see the file COPYING3.  If not see
 extern var_map coalesce_ssa_name (void);
 extern bool gimple_can_coalesce_p (tree, tree);
 extern bitmap get_parm_default_def_partitions (var_map);
+extern bitmap get_undefined_value_partitions (var_map);
 
 #endif /* GCC_TREE_SSA_COALESCE_H */