summaryrefslogtreecommitdiff
path: root/debian/patches/pr60902.diff
blob: b47bbcf2f4cc3ce62da91e2ea339ac5f556d6251 (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
# DP: Fix PR tree-optimization/60902, taken from the trunk.

gcc/

2014-04-28  Jeff Law  <law@redhat.com>

	PR tree-optimization/60902
	* tree-ssa-threadedge.c
	(record_temporary_equivalences_from_stmts_at_dest): Only iterate
	over real defs when invalidating outputs from statements that do not
	produce useful outputs for threading.

2014-04-23  Jeff Law  <law@redhat.com>

	PR tree-optimization/60902
	* tree-ssa-threadedge.c
	(record_temporary_equivalences_from_stmts_at_dest): Make sure to
	invalidate outputs from statements that do not produce useful
	outputs for threading.
 
gcc/testsuite/

2014-04-23  Jeff Law  <law@redhat.com>

	PR tree-optimization/60902
	* gcc.target/i386/pr60902.c: New test.

 
--- a/src/gcc/testsuite/gcc.target/i386/pr60902.c
+++ b/src/gcc/testsuite/gcc.target/i386/pr60902.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+extern void abort ();
+extern void exit (int);
+
+int x;
+
+foo()
+{
+  static int count;
+  count++;
+  if (count > 1)
+    abort ();
+}
+
+static inline int
+frob ()
+{
+  int a;
+  __asm__ ("mov %1, %0\n\t" : "=r" (a) : "m" (x));
+  x++;
+  return a;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 10 && frob () == 0; i++)
+    foo();
+  exit (0);
+}
--- a/src/gcc/tree-ssa-threadedge.c
+++ b/src/gcc/tree-ssa-threadedge.c
@@ -387,8 +387,35 @@
           && (gimple_code (stmt) != GIMPLE_CALL
               || gimple_call_lhs (stmt) == NULL_TREE
               || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
-	continue;
+	{
+	  /* STMT might still have DEFS and we need to invalidate any known
+	     equivalences for them.
 
+	     Consider if STMT is a GIMPLE_ASM with one or more outputs that
+	     feeds a conditional inside a loop.  We might derive an equivalence
+	     due to the conditional.  */
+	  tree op;
+	  ssa_op_iter iter;
+
+	  if (backedge_seen)
+	    FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
+	      {
+		/* This call only invalidates equivalences created by
+		   PHI nodes.  This is by design to keep the cost of
+		   of invalidation reasonable.  */
+		invalidate_equivalences (op, stack, src_map, dst_map);
+
+		/* However, conditionals can imply values for real
+		   operands as well.  And those won't be recorded in the
+		   maps.  In fact, those equivalences may be recorded totally
+		   outside the threading code.  We can just create a new
+		   temporary NULL equivalence here.  */
+	        record_temporary_equivalence (op, NULL_TREE, stack);
+	      }
+
+	  continue;
+	}
+
       /* The result of __builtin_object_size depends on all the arguments
 	 of a phi node. Temporarily using only one edge produces invalid
 	 results. For example