248 lines
7.2 KiB
Diff
248 lines
7.2 KiB
Diff
Upstream-Status: Inappropriate [Backport]
|
|
From 2631216d2fedc5339a5edcac64db1ab5d9269498 Mon Sep 17 00:00:00 2001
|
|
From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
|
|
Date: Mon, 28 Mar 2011 10:14:34 +0000
|
|
Subject: [PATCH 014/200] 2011-03-28 Richard Guenther <rguenther@suse.de>
|
|
|
|
Backport from mainline
|
|
2011-03-24 Richard Guenther <rguenther@suse.de>
|
|
|
|
PR middle-end/48269
|
|
* tree-object-size.c (addr_object_size): Do not double-account
|
|
for MEM_REF offsets.
|
|
|
|
* gcc.dg/builtin-object-size-10.c: New testcase.
|
|
|
|
2011-03-22 Richard Guenther <rguenther@suse.de>
|
|
|
|
PR tree-optimization/48228
|
|
* tree-vrp.c (vrp_visit_phi_node): Do not stop propagating
|
|
for single-arg PHIs.
|
|
|
|
* gcc.dg/Wstrict-overflow-23.c: New testcase.
|
|
|
|
2011-03-17 Richard Guenther <rguenther@suse.de>
|
|
|
|
PR middle-end/48134
|
|
* tree-ssa.c (insert_debug_temp_for_var_def): If we propagated
|
|
a value make sure to fold the statement.
|
|
|
|
* gcc.dg/pr48134.c: New testcase.
|
|
|
|
2011-03-15 Richard Guenther <rguenther@suse.de>
|
|
|
|
PR middle-end/48031
|
|
* fold-const.c (fold_indirect_ref_1): Do not create new variable-sized
|
|
or variable-indexed array accesses when in gimple form.
|
|
|
|
|
|
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@171595 138bc75d-0d04-0410-961f-82ee72b054a4
|
|
|
|
index 957049c..9a2f31f 100644
|
|
--- a/gcc/fold-const.c
|
|
+++ b/gcc/fold-const.c
|
|
@@ -15554,12 +15554,17 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
|
|
}
|
|
/* *(foo *)&fooarray => fooarray[0] */
|
|
else if (TREE_CODE (optype) == ARRAY_TYPE
|
|
- && type == TREE_TYPE (optype))
|
|
+ && type == TREE_TYPE (optype)
|
|
+ && (!in_gimple_form
|
|
+ || TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST))
|
|
{
|
|
tree type_domain = TYPE_DOMAIN (optype);
|
|
tree min_val = size_zero_node;
|
|
if (type_domain && TYPE_MIN_VALUE (type_domain))
|
|
min_val = TYPE_MIN_VALUE (type_domain);
|
|
+ if (in_gimple_form
|
|
+ && TREE_CODE (min_val) != INTEGER_CST)
|
|
+ return NULL_TREE;
|
|
return build4_loc (loc, ARRAY_REF, type, op, min_val,
|
|
NULL_TREE, NULL_TREE);
|
|
}
|
|
@@ -15633,7 +15638,9 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
|
|
|
|
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
|
|
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
|
|
- && type == TREE_TYPE (TREE_TYPE (subtype)))
|
|
+ && type == TREE_TYPE (TREE_TYPE (subtype))
|
|
+ && (!in_gimple_form
|
|
+ || TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST))
|
|
{
|
|
tree type_domain;
|
|
tree min_val = size_zero_node;
|
|
@@ -15641,6 +15648,9 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
|
|
type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
|
|
if (type_domain && TYPE_MIN_VALUE (type_domain))
|
|
min_val = TYPE_MIN_VALUE (type_domain);
|
|
+ if (in_gimple_form
|
|
+ && TREE_CODE (min_val) != INTEGER_CST)
|
|
+ return NULL_TREE;
|
|
return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
|
|
NULL_TREE);
|
|
}
|
|
new file mode 100644
|
|
index 0000000..16014bb
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-23.c
|
|
@@ -0,0 +1,31 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -Wstrict-overflow" } */
|
|
+
|
|
+unsigned int
|
|
+do_scrolling (unsigned int window_size, unsigned int writecost)
|
|
+{
|
|
+ unsigned int i = window_size;
|
|
+
|
|
+ int terminal_window_p = 0;
|
|
+ unsigned int queue = 0;
|
|
+
|
|
+ for (i = window_size; i; i--)
|
|
+ {
|
|
+ if (writecost < i)
|
|
+ ++queue;
|
|
+ else if (writecost & 1)
|
|
+ terminal_window_p = 1;
|
|
+ }
|
|
+
|
|
+ if (queue > 0)
|
|
+ {
|
|
+ if (!terminal_window_p)
|
|
+ {
|
|
+ terminal_window_p = 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (terminal_window_p)
|
|
+ return 100;
|
|
+ return 0;
|
|
+}
|
|
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-10.c b/gcc/testsuite/gcc.dg/builtin-object-size-10.c
|
|
new file mode 100644
|
|
index 0000000..6c7ed45
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-10.c
|
|
@@ -0,0 +1,26 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fdump-tree-objsz-details" } */
|
|
+
|
|
+typedef struct {
|
|
+ char sentinel[4];
|
|
+ char data[0];
|
|
+} drone_packet;
|
|
+typedef struct {
|
|
+ char type_str[16];
|
|
+ char channel_hop;
|
|
+} drone_source_packet;
|
|
+drone_packet *
|
|
+foo(char *x)
|
|
+{
|
|
+ drone_packet *dpkt = __builtin_malloc(sizeof(drone_packet)
|
|
+ + sizeof(drone_source_packet));
|
|
+ drone_source_packet *spkt = (drone_source_packet *) dpkt->data;
|
|
+ __builtin___snprintf_chk (spkt->type_str, 16,
|
|
+ 1, __builtin_object_size (spkt->type_str, 1),
|
|
+ "%s", x);
|
|
+ return dpkt;
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-tree-dump "maximum object size 21" "objsz" } } */
|
|
+/* { dg-final { scan-tree-dump "maximum subobject size 16" "objsz" } } */
|
|
+/* { dg-final { cleanup-tree-dump "objsz" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/pr48134.c b/gcc/testsuite/gcc.dg/pr48134.c
|
|
new file mode 100644
|
|
index 0000000..8dc5a6d
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/pr48134.c
|
|
@@ -0,0 +1,31 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fstack-check=specific -fno-tree-dse -fno-tree-fre -fno-tree-loop-optimize -g" } */
|
|
+
|
|
+struct S
|
|
+{
|
|
+ int w, z;
|
|
+};
|
|
+struct T
|
|
+{
|
|
+ struct S s;
|
|
+};
|
|
+
|
|
+int i;
|
|
+
|
|
+static inline struct S
|
|
+bar (struct S x)
|
|
+{
|
|
+ i++;
|
|
+ return x;
|
|
+}
|
|
+
|
|
+int
|
|
+foo (struct T t, struct S s)
|
|
+{
|
|
+ struct S *c = &s;
|
|
+ if (i)
|
|
+ c = &t.s;
|
|
+ t.s.w = 3;
|
|
+ s = bar (*c);
|
|
+ return t.s.w;
|
|
+}
|
|
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
|
|
index 6a74d19..043b445 100644
|
|
--- a/gcc/tree-object-size.c
|
|
+++ b/gcc/tree-object-size.c
|
|
@@ -348,8 +348,6 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
|
|
tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
|
|
if (bytes2 != error_mark_node)
|
|
{
|
|
- bytes2 = size_binop (PLUS_EXPR, bytes2,
|
|
- TREE_OPERAND (pt_var, 1));
|
|
if (TREE_CODE (bytes2) == INTEGER_CST
|
|
&& tree_int_cst_lt (pt_var_size, bytes2))
|
|
bytes2 = size_zero_node;
|
|
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
|
|
index 5c9e0d8..eaf3ef9 100644
|
|
--- a/gcc/tree-ssa.c
|
|
+++ b/gcc/tree-ssa.c
|
|
@@ -455,13 +455,19 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
|
|
continue;
|
|
|
|
if (value)
|
|
- FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
|
|
- /* unshare_expr is not needed here. vexpr is either a
|
|
- SINGLE_RHS, that can be safely shared, some other RHS
|
|
- that was unshared when we found it had a single debug
|
|
- use, or a DEBUG_EXPR_DECL, that can be safely
|
|
- shared. */
|
|
- SET_USE (use_p, value);
|
|
+ {
|
|
+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
|
|
+ /* unshare_expr is not needed here. vexpr is either a
|
|
+ SINGLE_RHS, that can be safely shared, some other RHS
|
|
+ that was unshared when we found it had a single debug
|
|
+ use, or a DEBUG_EXPR_DECL, that can be safely
|
|
+ shared. */
|
|
+ SET_USE (use_p, value);
|
|
+ /* If we didn't replace uses with a debug decl fold the
|
|
+ resulting expression. Otherwise we end up with invalid IL. */
|
|
+ if (TREE_CODE (value) != DEBUG_EXPR_DECL)
|
|
+ fold_stmt_inplace (stmt);
|
|
+ }
|
|
else
|
|
gimple_debug_bind_reset_value (stmt);
|
|
|
|
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
|
|
index 65d249f..280e6da 100644
|
|
--- a/gcc/tree-vrp.c
|
|
+++ b/gcc/tree-vrp.c
|
|
@@ -6619,6 +6619,7 @@ vrp_visit_phi_node (gimple phi)
|
|
edge; this helps us avoid an overflow infinity for conditionals
|
|
which are not in a loop. */
|
|
if (edges > 0
|
|
+ && gimple_phi_num_args (phi) > 1
|
|
&& edges == old_edges)
|
|
{
|
|
int cmp_min = compare_values (lhs_vr->min, vr_result.min);
|
|
--
|
|
1.7.0.4
|
|
|