diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-11-05 13:05:37 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-11-05 13:05:37 +0100 |
commit | 3ff2ca23dcf986e846691ec259da9243c636e64c (patch) | |
tree | 94f1319a87c64263ea23f14068264399661a6f16 /gcc | |
parent | f93a6a65b024af690d6b81778accea9587ad0a2a (diff) | |
download | gcc-3ff2ca23dcf986e846691ec259da9243c636e64c.zip gcc-3ff2ca23dcf986e846691ec259da9243c636e64c.tar.gz gcc-3ff2ca23dcf986e846691ec259da9243c636e64c.tar.bz2 |
re PR tree-optimization/58984 (wrong code at -Os and above on x86_64-linux-gnu in 64-bit mode)
PR tree-optimization/58984
* ipa-prop.c (ipa_load_from_parm_agg_1): Add SIZE_P argument,
set *SIZE_P if non-NULL on success.
(ipa_load_from_parm_agg, ipa_analyze_indirect_call_uses): Adjust
callers.
(ipcp_transform_function): Likewise. Punt if size of access
is different from TYPE_SIZE on v->value's type.
* gcc.c-torture/execute/pr58984.c: New test.
From-SVN: r204385
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr58984.c | 57 |
4 files changed, 84 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eecf65b..0651588 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-11-05 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58984 + * ipa-prop.c (ipa_load_from_parm_agg_1): Add SIZE_P argument, + set *SIZE_P if non-NULL on success. + (ipa_load_from_parm_agg, ipa_analyze_indirect_call_uses): Adjust + callers. + (ipcp_transform_function): Likewise. Punt if size of access + is different from TYPE_SIZE on v->value's type. + 2013-11-05 Tobias Burnus <burnus@net-b.de> * doc/invoke.texi (-fopenmp-simd): Document new option. diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index d9ea5dc..07af677 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -852,7 +852,7 @@ static bool ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors, struct param_analysis_info *parms_ainfo, gimple stmt, tree op, int *index_p, HOST_WIDE_INT *offset_p, - bool *by_ref_p) + HOST_WIDE_INT *size_p, bool *by_ref_p) { int index; HOST_WIDE_INT size, max_size; @@ -870,6 +870,8 @@ ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors, { *index_p = index; *by_ref_p = false; + if (size_p) + *size_p = size; return true; } return false; @@ -912,6 +914,8 @@ ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors, { *index_p = index; *by_ref_p = true; + if (size_p) + *size_p = size; return true; } return false; @@ -926,7 +930,7 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt, bool *by_ref_p) { return ipa_load_from_parm_agg_1 (info->descriptors, NULL, stmt, op, index_p, - offset_p, by_ref_p); + offset_p, NULL, by_ref_p); } /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result @@ -1826,7 +1830,7 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, if (gimple_assign_single_p (def) && ipa_load_from_parm_agg_1 (info->descriptors, parms_ainfo, def, gimple_assign_rhs1 (def), &index, &offset, - &by_ref)) + NULL, &by_ref)) { struct cgraph_edge *cs = ipa_note_param_call (node, index, call); cs->indirect_info->offset = offset; @@ -4567,7 +4571,7 @@ ipcp_transform_function (struct cgraph_node *node) struct ipa_agg_replacement_value *v; gimple stmt = gsi_stmt (gsi); tree rhs, val, t; - HOST_WIDE_INT offset; + HOST_WIDE_INT offset, size; int index; bool by_ref, vce; @@ -4594,13 +4598,15 @@ ipcp_transform_function (struct cgraph_node *node) continue; if (!ipa_load_from_parm_agg_1 (descriptors, parms_ainfo, stmt, - rhs, &index, &offset, &by_ref)) + rhs, &index, &offset, &size, &by_ref)) continue; for (v = aggval; v; v = v->next) if (v->index == index && v->offset == offset) break; - if (!v || v->by_ref != by_ref) + if (!v + || v->by_ref != by_ref + || tree_low_cst (TYPE_SIZE (TREE_TYPE (v->value)), 0) != size) continue; gcc_checking_assert (is_gimple_ip_invariant (v->value)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0686afa..d95fc2c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-05 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58984 + * gcc.c-torture/execute/pr58984.c: New test. + 2013-11-05 Andreas Schwab <schwab@suse.de> * g++.dg/ext/sync-4.C: Require sync_long_long_runtime support. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58984.c b/gcc/testsuite/gcc.c-torture/execute/pr58984.c new file mode 100644 index 0000000..e0f7669 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58984.c @@ -0,0 +1,57 @@ +/* PR tree-optimization/58984 */ + +struct S { int f0 : 8; int : 6; int f1 : 5; }; +struct T { char f0; int : 6; int f1 : 5; }; + +int a, *c = &a, e, n, b, m; + +static int +foo (struct S p) +{ + const unsigned short *f[36]; + for (; e < 2; e++) + { + const unsigned short **i = &f[0]; + *c ^= 1; + if (p.f1) + { + *i = 0; + return b; + } + } + return 0; +} + +static int +bar (struct T p) +{ + const unsigned short *f[36]; + for (; e < 2; e++) + { + const unsigned short **i = &f[0]; + *c ^= 1; + if (p.f1) + { + *i = 0; + return b; + } + } + return 0; +} + +int +main () +{ + struct S o = { 1, 1 }; + foo (o); + m = n || o.f0; + if (a != 1) + __builtin_abort (); + e = 0; + struct T p = { 1, 1 }; + bar (p); + m |= n || p.f0; + if (a != 0) + __builtin_abort (); + return 0; +} |