[mac80211]: wl12xx could need the wl128x firmware files, too
[openwrt/svn-archive/archive.git] / toolchain / gcc / patches / 4.8-linaro / 020-fix_pr58670.patch
1 --- a/gcc/cfgrtl.c
2 +++ b/gcc/cfgrtl.c
3 @@ -1784,10 +1784,18 @@ commit_one_edge_insertion (edge e)
4 }
5
6 /* If the source has one successor and the edge is not abnormal,
7 - insert there. Except for the entry block. */
8 + insert there. Except for the entry block.
9 + Don't do this if the predecessor ends in a jump other than
10 + unconditional simple jump. E.g. for asm goto that points all
11 + its labels at the fallthru basic block, we can't insert instructions
12 + before the asm goto, as the asm goto can have various of side effects,
13 + and can't emit instructions after the asm goto, as it must end
14 + the basic block. */
15 else if ((e->flags & EDGE_ABNORMAL) == 0
16 && single_succ_p (e->src)
17 - && e->src != ENTRY_BLOCK_PTR)
18 + && e->src != ENTRY_BLOCK_PTR
19 + && (!JUMP_P (BB_END (e->src))
20 + || simplejump_p (BB_END (e->src))))
21 {
22 bb = e->src;
23
24 --- a/gcc/stmt.c
25 +++ b/gcc/stmt.c
26 @@ -613,6 +613,9 @@ tree_conflicts_with_clobbers_p (tree t,
27 CLOBBERS is a list of STRING_CST nodes each naming a hard register
28 that is clobbered by this insn.
29
30 + LABELS is a list of labels, and if LABELS is non-NULL, FALLTHRU_BB
31 + should be the fallthru basic block of the asm goto.
32 +
33 Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
34 Some elements of OUTPUTS may be replaced with trees representing temporary
35 values. The caller should copy those temporary values to the originally
36 @@ -622,7 +625,8 @@ tree_conflicts_with_clobbers_p (tree t,
37
38 static void
39 expand_asm_operands (tree string, tree outputs, tree inputs,
40 - tree clobbers, tree labels, int vol, location_t locus)
41 + tree clobbers, tree labels, basic_block fallthru_bb,
42 + int vol, location_t locus)
43 {
44 rtvec argvec, constraintvec, labelvec;
45 rtx body;
46 @@ -643,6 +647,7 @@ expand_asm_operands (tree string, tree o
47 enum machine_mode *inout_mode = XALLOCAVEC (enum machine_mode, noutputs);
48 const char **constraints = XALLOCAVEC (const char *, noutputs + ninputs);
49 int old_generating_concat_p = generating_concat_p;
50 + rtx fallthru_label = NULL_RTX;
51
52 /* An ASM with no outputs needs to be treated as volatile, for now. */
53 if (noutputs == 0)
54 @@ -942,8 +947,24 @@ expand_asm_operands (tree string, tree o
55
56 /* Copy labels to the vector. */
57 for (i = 0, tail = labels; i < nlabels; ++i, tail = TREE_CHAIN (tail))
58 - ASM_OPERANDS_LABEL (body, i)
59 - = gen_rtx_LABEL_REF (Pmode, label_rtx (TREE_VALUE (tail)));
60 + {
61 + rtx r;
62 + /* If asm goto has any labels in the fallthru basic block, use
63 + a label that we emit immediately after the asm goto. Expansion
64 + may insert further instructions into the same basic block after
65 + asm goto and if we don't do this, insertion of instructions on
66 + the fallthru edge might misbehave. See PR58670. */
67 + if (fallthru_bb
68 + && label_to_block_fn (cfun, TREE_VALUE (tail)) == fallthru_bb)
69 + {
70 + if (fallthru_label == NULL_RTX)
71 + fallthru_label = gen_label_rtx ();
72 + r = fallthru_label;
73 + }
74 + else
75 + r = label_rtx (TREE_VALUE (tail));
76 + ASM_OPERANDS_LABEL (body, i) = gen_rtx_LABEL_REF (Pmode, r);
77 + }
78
79 generating_concat_p = old_generating_concat_p;
80
81 @@ -1067,6 +1088,9 @@ expand_asm_operands (tree string, tree o
82 emit_insn (body);
83 }
84
85 + if (fallthru_label)
86 + emit_label (fallthru_label);
87 +
88 /* For any outputs that needed reloading into registers, spill them
89 back to where they belong. */
90 for (i = 0; i < noutputs; ++i)
91 @@ -1087,6 +1111,7 @@ expand_asm_stmt (gimple stmt)
92 const char *s;
93 tree str, out, in, cl, labels;
94 location_t locus = gimple_location (stmt);
95 + basic_block fallthru_bb = NULL;
96
97 /* Meh... convert the gimple asm operands into real tree lists.
98 Eventually we should make all routines work on the vectors instead
99 @@ -1122,6 +1147,9 @@ expand_asm_stmt (gimple stmt)
100 n = gimple_asm_nlabels (stmt);
101 if (n > 0)
102 {
103 + edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs);
104 + if (fallthru)
105 + fallthru_bb = fallthru->dest;
106 t = labels = gimple_asm_label_op (stmt, 0);
107 for (i = 1; i < n; i++)
108 t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
109 @@ -1147,7 +1175,7 @@ expand_asm_stmt (gimple stmt)
110
111 /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
112 OUTPUTS some trees for where the values were actually stored. */
113 - expand_asm_operands (str, outputs, in, cl, labels,
114 + expand_asm_operands (str, outputs, in, cl, labels, fallthru_bb,
115 gimple_asm_volatile_p (stmt), locus);
116
117 /* Copy all the intermediate outputs into the specified outputs. */
118 --- /dev/null
119 +++ b/gcc/testsuite/gcc.dg/torture/pr58670.c
120 @@ -0,0 +1,47 @@
121 +/* PR middle-end/58670 */
122 +/* { dg-do run { target i?86-*-* x86_64-*-* } } */
123 +
124 +#if defined (__i386__) || defined (__x86_64__)
125 +#define ASM_STR "bts $1, %0; jc %l[lab]"
126 +#endif
127 +
128 +__attribute__((noinline, noclone)) int
129 +foo (int a, int b)
130 +{
131 + if (a)
132 + return -3;
133 +#ifdef ASM_STR
134 + asm volatile goto (ASM_STR : : "m" (b) : "memory" : lab);
135 + return 0;
136 +lab:
137 +#endif
138 + return 0;
139 +}
140 +
141 +int
142 +bar (int a, int b)
143 +{
144 + if (a)
145 + return -3;
146 +#ifdef ASM_STR
147 + asm volatile goto (ASM_STR : : "m" (b) : "memory" : lab);
148 + return 0;
149 +lab:
150 +#endif
151 + return 0;
152 +}
153 +
154 +int
155 +main ()
156 +{
157 + if (foo (1, 0) != -3
158 + || foo (0, 3) != 0
159 + || foo (1, 0) != -3
160 + || foo (0, 0) != 0
161 + || bar (1, 0) != -3
162 + || bar (0, 3) != 0
163 + || bar (1, 0) != -3
164 + || bar (0, 0) != 0)
165 + __builtin_abort ();
166 + return 0;
167 +}