From 561593c104a3fcce354d644b12072b1da8690baa Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 8 Oct 2017 21:13:52 +0000 Subject: [PATCH] tree-outof-ssa.h (ssaexpand): Add partitions_for_undefined_values. * 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) : 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 | 15 ++++++++ gcc/expr.c | 33 ++++++++++++---- gcc/loop-iv.c | 2 +- gcc/testsuite/ChangeLog | 4 ++ .../gcc.c-torture/execute/20171008-1.c | 38 +++++++++++++++++++ gcc/tree-outof-ssa.c | 2 + gcc/tree-outof-ssa.h | 16 ++++++++ gcc/tree-ssa-coalesce.c | 28 +++++++++++++- gcc/tree-ssa-coalesce.h | 1 + 9 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20171008-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96acd2be639..baf6a6d96bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-10-08 Eric Botcazou + + * 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) : 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 * builtins.def (BUILT_IN_SETJMP): Revert latest change. diff --git a/gcc/expr.c b/gcc/expr.c index 2f8432d92cc..134ee731c29 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 1d0c66f2b2f..45e822980ff 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 e7045e8cba8..c2a658c3dcf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-10-08 Eric Botcazou + + * gcc.c-torture/execute/20171008-1.c: New test. + 2017-10-03 Jeff Law * 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 00000000000..cde807a70b3 --- /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 0ce6c155bd3..6327c07c68b 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 e751a26f848..1220b6256ca 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 e166314ed4d..3938f064f67 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 9eebdddf917..98e61c5d34a 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 */ -- 2.30.2