aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-11-05 13:05:37 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-11-05 13:05:37 +0100
commit3ff2ca23dcf986e846691ec259da9243c636e64c (patch)
tree94f1319a87c64263ea23f14068264399661a6f16 /gcc
parentf93a6a65b024af690d6b81778accea9587ad0a2a (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/ipa-prop.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58984.c57
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;
+}