1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
Upstream-Status: Inappropriate [Backport]
From 5b05a527f1368e4ca9f71a8ec8124a2c64661007 Mon Sep 17 00:00:00 2001
From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 12 Apr 2011 13:44:33 +0000
Subject: [PATCH 109/200] PR rtl-optimization/48549
* combine.c (propagate_for_debug): Also stop after BB_END of
this_basic_block. Process LAST and just stop processing after it.
(combine_instructions): If last_combined_insn has been deleted,
set last_combined_insn to its PREV_INSN.
* g++.dg/opt/pr48549.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@172319 138bc75d-0d04-0410-961f-82ee72b054a4
index 5f179c6..d563999 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1178,8 +1178,13 @@ combine_instructions (rtx f, unsigned int nregs)
next = 0;
if (NONDEBUG_INSN_P (insn))
{
+ while (last_combined_insn
+ && INSN_DELETED_P (last_combined_insn))
+ last_combined_insn = PREV_INSN (last_combined_insn);
if (last_combined_insn == NULL_RTX
- || DF_INSN_LUID (last_combined_insn) < DF_INSN_LUID (insn))
+ || BARRIER_P (last_combined_insn)
+ || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
+ || DF_INSN_LUID (last_combined_insn) <= DF_INSN_LUID (insn))
last_combined_insn = insn;
/* See if we know about function return values before this
@@ -2435,19 +2440,21 @@ propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
}
/* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
- and LAST. */
+ and LAST, not including INSN, but including LAST. Also stop at the end
+ of THIS_BASIC_BLOCK. */
static void
propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src)
{
- rtx next, loc;
+ rtx next, loc, end = NEXT_INSN (BB_END (this_basic_block));
struct rtx_subst_pair p;
p.to = src;
p.adjusted = false;
next = NEXT_INSN (insn);
- while (next != last)
+ last = NEXT_INSN (last);
+ while (next != last && next != end)
{
insn = next;
next = NEXT_INSN (insn);
new file mode 100644
index 0000000..30799ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr48549.C
@@ -0,0 +1,63 @@
+// PR rtl-optimization/48549
+// { dg-do compile }
+// { dg-options "-fcompare-debug -O2" }
+
+void
+foo (void *from, void *to)
+{
+ long offset = reinterpret_cast <long>(to) - reinterpret_cast <long>(from);
+ if (offset != static_cast <int>(offset))
+ *(int *) 0xC0DE = 0;
+ reinterpret_cast <int *>(from)[1] = offset;
+}
+struct A
+{
+ A () : a () {}
+ A (void *x) : a (x) {}
+ void *bar () { return a; }
+ void *a;
+};
+struct C;
+struct D;
+struct E : public A
+{
+ C m1 (int);
+ D m2 ();
+ E () {}
+ E (A x) : A (x) {}
+};
+struct C : public E
+{
+ C () {}
+ C (void *x) : E (x) {}
+};
+struct D : public E
+{
+ D (void *x) : E (x) {}
+};
+C
+E::m1 (int x)
+{
+ return (reinterpret_cast <char *>(bar ()) + x);
+}
+D
+E::m2 ()
+{
+ return reinterpret_cast <char *>(bar ());
+}
+struct B
+{
+ E a;
+ unsigned b : 16;
+ unsigned c : 1;
+};
+void
+baz (B *x)
+{
+ for (unsigned i = 0; i < 64; i++)
+ {
+ D d = x[i].a.m2 ();
+ C c = x[i].a.m1 (x[i].c);
+ foo (d.bar (), c.bar ());
+ }
+}
--
1.7.0.4
|