aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/expr.c33
-rw-r--r--gcc/loop-iv.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20171008-1.c38
-rw-r--r--gcc/tree-outof-ssa.c2
-rw-r--r--gcc/tree-outof-ssa.h16
-rw-r--r--gcc/tree-ssa-coalesce.c28
-rw-r--r--gcc/tree-ssa-coalesce.h1
9 files changed, 130 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 96acd2b..baf6a6d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
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.
2017-10-08 Jan Hubicka <hubicka@ucw.cz>
diff --git a/gcc/expr.c b/gcc/expr.c
index 2f8432d..134ee73 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;
}
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 1d0c66f..45e8229 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e7045e8..c2a658c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..cde807a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20171008-1.c
@@ -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;
+}
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 0ce6c15..6327c07 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -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);
}
diff --git a/gcc/tree-outof-ssa.h b/gcc/tree-outof-ssa.h
index e751a26..1220b62 100644
--- a/gcc/tree-outof-ssa.h
+++ b/gcc/tree-outof-ssa.h
@@ -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);
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index e166314..3938f06 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-coalesce.h b/gcc/tree-ssa-coalesce.h
index 9eebddd..98e61c5 100644
--- a/gcc/tree-ssa-coalesce.h
+++ b/gcc/tree-ssa-coalesce.h
@@ -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 */