summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0109-PR-rtl-optimization-48549.patch
blob: c0b3f63526df33f4412f01e8ec3cfd1f42836c1a (plain)
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

OpenPOWER on IntegriCloud