fix installation
[buildroot.git] / toolchain / gcc / 4.3.2 / 900-if-ifcvt-noce_emit_store_flag.patch
blob5cfe48a766b4b5d76e3beccd8bda1df3e93e0eef
1 Date: Mon, 29 Sep 2008 17:11:55 +0000 (UTC)
2 From: "Joseph S dot Myers"
3 Subject: Fix if-conversion bug reversing conditions
4 Message-ID: <Pine.LNX.4.64.0809291710170.16546@digraph.polyomino.org.uk>
6 This patch fixes an if-conversion problem that manifested itself in a
7 4.3-based toolchain as execution failures on powerpc-linux-gnu
8 -msoft-float:
10 FAIL: gcc.c-torture/execute/stdarg-3.c execution, -O3 -fomit-frame-pointer -funroll-loops
11 FAIL: gcc.c-torture/execute/stdarg-3.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
13 I don't have a testcase manifesting the bug on trunk but believe it is
14 still present there.
16 A loop is unrolled, and an initial test for whether it has an even or
17 an odd number of iterations gets wrongly inverted by the post-combine
18 if-conversion pass (ce2). After combine the relevant insns (for a
19 reduced version of stdarg-3.c with the 4.3-based toolchain) look like:
21 (insn 144 113 145 3 (parallel [
22 (set (reg:CC 166)
23 (compare:CC (zero_extract:SI (reg/v:SI 120 [ j ])
24 (const_int 1 [0x1])
25 (const_int 31 [0x1f]))
26 (const_int 0 [0x0])))
27 (clobber (scratch:SI))
28 ]) 159 {*extzvsi_internal1} (nil))
30 (jump_insn 145 144 70 3 (set (pc)
31 (if_then_else (ne (reg:CC 166)
32 (const_int 0 [0x0]))
33 (label_ref:SI 178)
34 (pc))) 560 {*rs6000.md:13937} (expr_list:REG_DEAD (reg:CC 166)
35 (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
36 (nil))))
37 ;; End of basic block 3 -> ( 7 4)
39 ;; Succ edge 7 [50.0%]
40 ;; Succ edge 4 [50.0%] (fallthru)
42 ...
44 ;; Start of basic block ( 3) -> 7
46 ;; Pred edge 3 [50.0%]
47 (code_label 178 81 137 7 11 "" [1 uses])
49 (note 137 178 139 7 [bb 7] NOTE_INSN_BASIC_BLOCK)
51 (insn 139 137 181 7 stdarg-3.c:13 (set (reg/v:SI 120 [ j ])
52 (plus:SI (reg/v:SI 120 [ j ])
53 (const_int -1 [0xffffffffffffffff]))) 79 {*addsi3_internal1} (nil))
55 (jump_insn 181 139 182 7 (set (pc)
56 (label_ref 70)) -1 (nil))
57 ;; End of basic block 7 -> ( 4)
59 find_if_header duly enters noce_find_if_block with then_edge being the
60 EDGE_FALLTHRU edge (to block 4) and ELSE_EDGE being the edge to block
61 7. This reaches the IF-ELSE-JOIN case and sets then_else_reversed, so
62 then_bb, insn_a as set in noce_process_if_block, is now block 7.
63 noce_get_condition duly inverts the jump condition. This is correct
64 so far; if_info->cond is meant to be the condition for going to
65 if_info->insn_b (though the comments never say so explicitly, a lot of
66 code only makes sense that way).
68 The code in question - subtracting 1 from a REG in the insn_a case
69 (i.e. if if_info->cond is false) - is handled by noce_try_addcc. This
70 reaches the
72 /* If that fails, construct conditional increment or decrement using
73 setcc. */
75 case and so calls noce_emit_store_flag with REVERSEP set to 1. Thus
76 noce_emit_store_flag knows to store the reverse of if_info->cond,
77 which would be the right value to subtract. However, it then runs
78 into the case
80 /* If earliest == jump, or when the condition is complex, try to
81 build the store_flag insn directly. */
83 where it uses the condition from the original jump, ignoring the
84 possibility of this condition having been reversed in order to get the
85 correct insn_b condition.
87 This patch makes noce_emit_store_flag check the same conditions as
88 noce_get_condition for whether to reverse the condition, when it goes
89 back to the original jump.
91 Bootstrapped with no regressions on i686-pc-linux-gnu. Tested with no
92 regressions with cross to powerpc-linux-gnu -msoft-float. OK to
93 commit?
95 2008-09-29 Joseph Myers <joseph@codesourcery.com>
97 * ifcvt.c (noce_emit_store_flag): If using condition from original
98 jump, reverse it if if_info->cond was reversed.
100 Index: ifcvt.c
101 ===================================================================
102 --- gcc-4.3.2.old/gcc/ifcvt.c (revision 140752)
103 +++ gcc-4.3.2/gcc/ifcvt.c (working copy)
104 @@ -666,7 +666,15 @@
105 build the store_flag insn directly. */
107 if (cond_complex)
108 - cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
110 + rtx set = pc_set (if_info->jump);
111 + cond = XEXP (SET_SRC (set), 0);
112 + if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
113 + && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump))
114 + reversep = !reversep;
115 + if (if_info->then_else_reversed)
116 + reversep = !reversep;
119 if (reversep)
120 code = reversed_comparison_code (cond, if_info->jump);