This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/32769] New: __builtin_eh_return broken by dataflow merge
- From: "danglin at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 14 Jul 2007 19:47:02 -0000
- Subject: [Bug middle-end/32769] New: __builtin_eh_return broken by dataflow merge
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
All EH related tests fail on all hppa targets using dwarf2 EH support.
See for example: <http://gcc.gnu.org/ml/gcc-testresults/2007-07/msg00634.html>.
I looked at the failure of gcc.dg/cleanup-8.c. The following code appears to
be miscompiled:
#define uw_install_context(CURRENT, TARGET) \
do \
{ \
long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
__builtin_eh_return (offset, handler); \
} \
while (0)
Prior to the dataflow merge, we have the following assembler code:
0x00013308 <_Unwind_ForcedUnwind+384>: b,l 0x113bc <uw_install_context_1>,rp
0x0001330c <_Unwind_ForcedUnwind+388>: copy r3,r25
0x00013310 <_Unwind_ForcedUnwind+392>: copy ret0,ret1
0x00013314 <_Unwind_ForcedUnwind+396>: ldw -164(sp),ret0
0x00013318 <_Unwind_ForcedUnwind+400>: b,l 0x13278
<_Unwind_ForcedUnwind+240>,r0
0x0001331c <_Unwind_ForcedUnwind+404>: stw ret0,-4d4(sp)
The last instruction stores the new address for the return pointer into the
frame. The epilogue at _Unwind_ForcedUnwind+240 loads the return pointer
from this location.
After the dataflow merge, we have the following:
0x000137f4 <_Unwind_ForcedUnwind+384>: b,l 0x10e34 <uw_install_context_1>,rp
0x000137f8 <_Unwind_ForcedUnwind+388>: copy r3,r25
0x000137fc <_Unwind_ForcedUnwind+392>: b,l 0x13764
<_Unwind_ForcedUnwind+240>,r0
0x00013800 <_Unwind_ForcedUnwind+396>: copy ret0,ret1
The new return pointer isn't saved in the frame, so _Unwind_ForcedUnwind
returns to the wrong place. It looks like the insns are dropped the dse1
pass.
We have the following after the cse2 pass:
;; Start of basic block ( 2) -> 4
;; bb 4 artificial_defs: { }
;; bb 4 artificial_uses: { u54(3){ }u55(19){ }u56(30){ }}
;; lr in 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; lr use 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; lr def 0 [%r0] 1 [%r1] 2 [%r2] 4 [%r4] 19 [%r19] 20 [%r20] 21 [%r21]
2
2 [%r22] 23 [%r23] 24 [%r24] 25 [%r25] 26 [%r26] 27 [%r27] 28 [%r28] 29 [%r29]
3
1 [%r31] 32 [%fr4] 33 [%fr4R] 34 [%fr5] 35 [%fr5R] 36 [%fr6] 37 [%fr6R] 38
[%fr7
] 39 [%fr7R] 40 [%fr8] 41 [%fr8R] 42 [%fr9] 43 [%fr9R] 44 [%fr10] 45 [%fr10R]
46
[%fr11] 47 [%fr11R] 68 [%fr22] 69 [%fr22R] 70 [%fr23] 71 [%fr23R] 72 [%fr24]
73 [%fr24R] 74 [%fr25] 75 [%fr25R] 76 [%fr26] 77 [%fr26R] 78 [%fr27] 79
[%fr27R] 80 [%fr28] 81 [%fr28R] 82 [%fr29] 83 [%fr29R] 84 [%fr30] 85 [%fr30R]
86 [%fr31] 87 [%fr31R] 88 [SAR] 94 95 99
;; live in 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; live gen 25 [%r25] 26 [%r26] 28 [%r28] 29 [%r29] 94 95
;; live kill 1 [%r1] 2 [%r2] 4 [%r4] 28 [%r28] 99
;; Pred edge 2 [1.0%]
(code_label 34 47 35 4 546 "" [1 uses])
(note 35 34 37 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 37 35 38 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg:SI 26
%r26)
(reg/f:SI 113)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg/f:SI 113)
(expr_list:REG_EQUAL (plus:SI (reg/f:SI 3 %r3)
(const_int 8 [0x8]))
(nil))))
(insn 38 37 39 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg:SI 25
%r25)
(reg/f:SI 104)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg/f:SI 104)
(expr_list:REG_EQUAL (plus:SI (reg/f:SI 3 %r3)
(const_int 496 [0x1f0]))
(nil))))
(call_insn 39 38 40 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (parallel [
(set (reg:SI 28 %r28)
(call (mem:SI (symbol_ref/v:SI ("@uw_install_context_1") [flags
0x203] <function_decl 0x404bc080 uw_install_context_1>) [0 S4 A32])
(const_int 16 [0x10])))
(clobber (reg:SI 1 %r1))
(clobber (reg:SI 2 %r2))
(clobber (reg:SI 4 %r4))
(use (reg:SI 19 %r19))
(use (const_int 0 [0x0]))
]) 216 {call_val_symref_pic} (expr_list:REG_DEAD (reg:SI 26 %r26)
(expr_list:REG_DEAD (reg:SI 25 %r25)
(nil)))
(expr_list:REG_DEP_TRUE (use (reg:SI 25 %r25))
(expr_list:REG_DEP_TRUE (use (reg:SI 26 %r26))
(nil))))
(insn 40 39 41 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg/v:SI 95 [
offset ])
(reg:SI 28 %r28)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg:SI 28 %r28)
(nil)))
(insn 41 40 51 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg/v/f:SI 94
[ handler ])
(mem/s/f/c:SI (plus:SI (reg/f:SI 3 %r3)
(const_int 860 [0x35c])) [4 cur_context.ra+0 S4 A32])) 37
{*pa.md:2543} (nil))
(insn 51 41 52 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (clobber (reg/i:SI
28 %r28 [ <result> ])) -1 (expr_list:REG_UNUSED (reg/i:SI 28 %r28 [ <result> ])
(nil)))
(insn 52 51 53 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (clobber (reg:SI 99
[ <result> ])) -1 (expr_list:REG_UNUSED (reg:SI 99 [ <result> ])
(nil)))
(insn 53 52 54 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (set (reg:SI 29 %r29
[ offset ])
(reg/v:SI 95 [ offset ])) 37 {*pa.md:2543} (expr_list:REG_DEAD
(reg/v:SI 95 [ offset ])
(nil)))
(insn 54 53 55 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (set (mem:SI
(plus:SI (reg/f:SI 3 %r3)
(const_int -20 [0xffffffec])) [0 S4 A32])
(reg/v/f:SI 94 [ handler ])) 37 {*pa.md:2543} (expr_list:REG_DEAD
(reg/v/f:SI 94 [ handler ])
(nil)))
;; End of basic block 4 -> ( 5)
;; lr out 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; live out 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30]
;; Succ edge 5 [100.0%] (fallthru)
;; Start of basic block ( 3 4) -> 5
;; bb 5 artificial_defs: { }
;; bb 5 artificial_uses: { u76(3){ }u77(19){ }u78(30){ }}
;; lr in 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; lr use 3 [%r3] 19 [%r19] 30 [%r30] 99
;; lr def 28 [%r28]
;; live in 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; live gen 28 [%r28]
;; live kill
;; Pred edge 3 [100.0%] (fallthru)
;; Pred edge 4 [100.0%] (fallthru)
(code_label 55 54 66 5 548 "" [0 uses])
(note 66 55 56 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
(insn 56 66 62 5 ../../../gcc/libgcc/../gcc/unwind.inc:216 (set (reg/i:SI 28
%r28 [ <result> ])
(reg:SI 99 [ <result> ])) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg:SI
99 [ <result> ])
(nil)))
(insn 62 56 0 5 ../../../gcc/libgcc/../gcc/unwind.inc:216 (use (reg/i:SI 28
%r28 [ <result> ])) -1 (nil))
;; End of basic block 5 -> ( 1)
;; lr out 3 [%r3] 19 [%r19] 28 [%r28] 29 [%r29] 30 [%r30]
;; live out 3 [%r3] 19 [%r19] 28 [%r28] 29 [%r29] 30 [%r30]
;; Succ edge EXIT [100.0%] (fallthru)
We have the following after the dse1 pass:
...
**scanning insn=41
mem: (plus:SI (reg/f:SI 3 %r3)
(const_int 860 [0x35c]))
after cselib_expand address: (plus:SI (reg/f:SI 3 %r3)
(const_int 860 [0x35c]))
after canon_rtx address: (plus:SI (reg/f:SI 3 %r3)
(const_int 860 [0x35c]))
gid=4 offset=860
processing const load gid=4[860..864)
mems_found = 0, cannot_delete = true
...
**scanning insn=54
mem: (plus:SI (reg/f:SI 3 %r3)
(const_int -20 [0xffffffec]))
after cselib_expand address: (plus:SI (reg/f:SI 3 %r3)
(const_int -20 [0xffffffec]))
after canon_rtx address: (plus:SI (reg/f:SI 3 %r3)
(const_int -20 [0xffffffec]))
gid=4 offset=-20
processing const base store gid=4[-20..-16)
mems_found = 1, cannot_delete = false
...
starting to process insn 54
v: 1, 2, 3, 4
i = -20, index = 4
i = -19, index = 3
i = -18, index = 2
i = -17, index = 1
deferring deletion of insn with uid = 54.
...
starting to process insn 41
v: 1, 2, 3, 4
regular read
...
;; Start of basic block ( 2) -> 4
;; bb 4 artificial_defs: { }
;; bb 4 artificial_uses: { u54(3){ }u55(19){ }u56(30){ }}
;; lr in 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; lr use 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; lr def 0 [%r0] 1 [%r1] 2 [%r2] 4 [%r4] 19 [%r19] 20 [%r20] 21 [%r21]
2
2 [%r22] 23 [%r23] 24 [%r24] 25 [%r25] 26 [%r26] 27 [%r27] 28 [%r28] 29 [%r29]
3
1 [%r31] 32 [%fr4] 33 [%fr4R] 34 [%fr5] 35 [%fr5R] 36 [%fr6] 37 [%fr6R] 38
[%fr7
] 39 [%fr7R] 40 [%fr8] 41 [%fr8R] 42 [%fr9] 43 [%fr9R] 44 [%fr10] 45 [%fr10R]
46
[%fr11] 47 [%fr11R] 68 [%fr22] 69 [%fr22R] 70 [%fr23] 71 [%fr23R] 72 [%fr24]
73
[%fr24R] 74 [%fr25] 75 [%fr25R] 76 [%fr26] 77 [%fr26R] 78 [%fr27] 79 [%fr27R]
8
0 [%fr28] 81 [%fr28R] 82 [%fr29] 83 [%fr29R] 84 [%fr30] 85 [%fr30R] 86 [%fr31]
8
7 [%fr31R] 88 [SAR] 94 95 99
;; live in 3 [%r3] 19 [%r19] 30 [%r30] 104 113
;; live gen 25 [%r25] 26 [%r26] 28 [%r28] 29 [%r29] 94 95
;; live kill 1 [%r1] 2 [%r2] 4 [%r4] 28 [%r28] 99
;; Pred edge 2 [1.0%]
(code_label 34 47 35 4 546 "" [1 uses])
(note 35 34 37 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 37 35 38 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg:SI 26
%r26)
(reg/f:SI 113)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg/f:SI 113)
(expr_list:REG_EQUAL (plus:SI (reg/f:SI 3 %r3)
(const_int 8 [0x8]))
(nil))))
(insn 38 37 39 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg:SI 25
%r25)
(reg/f:SI 104)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg/f:SI 104)
(expr_list:REG_EQUAL (plus:SI (reg/f:SI 3 %r3)
(const_int 496 [0x1f0]))
(nil))))
(call_insn 39 38 40 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (parallel [
(set (reg:SI 28 %r28)
(call (mem:SI (symbol_ref/v:SI ("@uw_install_context_1") [flags
0x203] <function_decl 0x404bc080 uw_install_context_1>) [0 S4 A32])
(const_int 16 [0x10])))
(clobber (reg:SI 1 %r1))
(clobber (reg:SI 2 %r2))
(clobber (reg:SI 4 %r4))
(use (reg:SI 19 %r19))
(use (const_int 0 [0x0]))
]) 216 {call_val_symref_pic} (expr_list:REG_DEAD (reg:SI 26 %r26)
(expr_list:REG_DEAD (reg:SI 25 %r25)
(nil)))
(expr_list:REG_DEP_TRUE (use (reg:SI 25 %r25))
(expr_list:REG_DEP_TRUE (use (reg:SI 26 %r26))
(nil))))
(insn 40 39 41 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg/v:SI 95 [
offset ])
(reg:SI 28 %r28)) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg:SI 28 %r28)
(nil)))
(insn 41 40 51 4 ../../../gcc/libgcc/../gcc/unwind.inc:215 (set (reg/v/f:SI 94
[ handler ])
(mem/s/f/c:SI (plus:SI (reg/f:SI 3 %r3)
(const_int 860 [0x35c])) [4 cur_context.ra+0 S4 A32])) 37
{*pa.md:2543} (nil))
(insn 51 41 52 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (clobber (reg/i:SI
28 %r28 [ <result> ])) -1 (expr_list:REG_UNUSED (reg/i:SI 28 %r28 [ <result> ])
(nil)))
(insn 52 51 53 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (clobber (reg:SI 99
[ <result> ])) -1 (expr_list:REG_UNUSED (reg:SI 99 [ <result> ])
(nil)))
(insn 53 52 55 4 ../../../gcc/libgcc/../gcc/unwind.inc:216 (set (reg:SI 29 %r29
[ offset ])
(reg/v:SI 95 [ offset ])) 37 {*pa.md:2543} (expr_list:REG_DEAD
(reg/v:SI 95 [ offset ])
(nil)))
;; End of basic block 4 -> ( 5)
;; lr out 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; live out 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30]
;; Succ edge 5 [100.0%] (fallthru)
;; Start of basic block ( 3 4) -> 5
;; bb 5 artificial_defs: { }
;; bb 5 artificial_uses: { u76(3){ }u77(19){ }u78(30){ }}
;; lr in 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; lr use 3 [%r3] 19 [%r19] 30 [%r30] 99
;; lr def 28 [%r28]
;; live in 3 [%r3] 19 [%r19] 29 [%r29] 30 [%r30] 99
;; live gen 28 [%r28]
;; live kill
;; Pred edge 3 [100.0%] (fallthru)
;; Pred edge 4 [100.0%] (fallthru)
(code_label 55 53 66 5 548 "" [0 uses])
(note 66 55 56 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
(insn 56 66 62 5 ../../../gcc/libgcc/../gcc/unwind.inc:216 (set (reg/i:SI 28
%r28 [ <result> ])
(reg:SI 99 [ <result> ])) 37 {*pa.md:2543} (expr_list:REG_DEAD (reg:SI
99 [ <result> ])
(nil)))
(insn 62 56 0 5 ../../../gcc/libgcc/../gcc/unwind.inc:216 (use (reg/i:SI 28
%r28 [ <result> ])) -1 (nil))
;; End of basic block 5 -> ( 1)
;; lr out 3 [%r3] 19 [%r19] 28 [%r28] 29 [%r29] 30 [%r30]
;; live out 3 [%r3] 19 [%r19] 28 [%r28] 29 [%r29] 30 [%r30]
;; Succ edge EXIT [100.0%] (fallthru)
starting the processing of deferred insns
deleting insn with uid = 54.
ending the processing of deferred insns
--
Summary: __builtin_eh_return broken by dataflow merge
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: danglin at gcc dot gnu dot org
GCC build triplet: hppa*-*-*
GCC host triplet: hppa*-*-*
GCC target triplet: hppa*-*-*
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32769