Jakub Jelinek
2007-10-11 18:49:06 UTC
Hi!
The attached testcase fails on ppc with -m32 -O2 -ftrapv.
In *.unshare we have:
(insn 44 43 45 3 pr33644.c:15 (set (reg:SI 3 3)
(reg/f:SI 155 [ D.1244 ])) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 45 44 46 3 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 115 virtual-stack-vars)) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
...
(insn 47 46 48 3 pr33644.c:15 (set (reg:SI 156)
(reg:SI 3 3)) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_RETVAL 44 (expr_list:REG_EQUAL (minus:SI (reg/f:SI 155 [ D.1244 ])
(reg/f:SI 115 virtual-stack-vars))
(nil)))))
First vregs inserts a new insn between 44 and 45 to instantiate
virtual-stack-vars:
(insn 44 43 84 3 pr33644.c:15 (set (reg:SI 3 3)
(reg/f:SI 155 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 3 pr33644.c:15 (set (reg:SI 169)
(plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))) -1 (nil))
(insn 45 84 46 3 pr33644.c:15 (set (reg:SI 4 4)
(reg:SI 169)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
and later on CSE finds sfp + 8 is already in pseudo 168:
(insn 44 43 84 2 pr33644.c:15 (set (reg:SI 3 3 [ D.1244 ])
(reg:SI 3 3 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 2 pr33644.c:15 (set (reg/f:SI 169)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_EQUAL (plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))
(nil)))
(insn 45 84 46 2 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 169)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
and then forwprop replaces pseudo 169 with pseudo 168 in insn 45:
(insn 44 42 84 2 pr33644.c:15 (set (reg:SI 3 3 [ D.1244 ])
(reg:SI 3 3 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 2 pr33644.c:15 (set (reg/f:SI 169)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_EQUAL (plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))
(nil)))
(insn 45 84 46 2 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
When DCE is run during GCSE, insn 44 is being deleted as it is a noop_move_p
and moves REG_LIBCALL note to the following insn (84). But that one doesn't have
REG_LIBCALL_ID note and in this case wasn't even marked, as it is unneeded
and so the next delete_unmarked_insns loop iteration kills even that insn.
This means we end up with a REG_RETVAL note without corresponding RET_LIBCALL
and ICE later on.
I believe it is not a bug to have non-REG_LIBCALL_ID insns within
a libcall sequence as long as they are either useless or something needed
by the libcall sequence insns (i.e. they can be deleted whenever the whole
libcall sequence is killed, but can be also deleted if they are not needed
individually). If so, attached are two possible patches which fix this,
one will move the REG_LIBCALL note to the first insn that is actually not
going to be deleted, the other to the first REG_LIBCALL_ID insn (which is supposed
to be marked by mark_libcall). I prefer the latter patch.
Ok for trunk?
Jakub
The attached testcase fails on ppc with -m32 -O2 -ftrapv.
In *.unshare we have:
(insn 44 43 45 3 pr33644.c:15 (set (reg:SI 3 3)
(reg/f:SI 155 [ D.1244 ])) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 45 44 46 3 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 115 virtual-stack-vars)) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
...
(insn 47 46 48 3 pr33644.c:15 (set (reg:SI 156)
(reg:SI 3 3)) -1 (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_RETVAL 44 (expr_list:REG_EQUAL (minus:SI (reg/f:SI 155 [ D.1244 ])
(reg/f:SI 115 virtual-stack-vars))
(nil)))))
First vregs inserts a new insn between 44 and 45 to instantiate
virtual-stack-vars:
(insn 44 43 84 3 pr33644.c:15 (set (reg:SI 3 3)
(reg/f:SI 155 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 3 pr33644.c:15 (set (reg:SI 169)
(plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))) -1 (nil))
(insn 45 84 46 3 pr33644.c:15 (set (reg:SI 4 4)
(reg:SI 169)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
and later on CSE finds sfp + 8 is already in pseudo 168:
(insn 44 43 84 2 pr33644.c:15 (set (reg:SI 3 3 [ D.1244 ])
(reg:SI 3 3 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 2 pr33644.c:15 (set (reg/f:SI 169)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_EQUAL (plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))
(nil)))
(insn 45 84 46 2 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 169)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
and then forwprop replaces pseudo 169 with pseudo 168 in insn 45:
(insn 44 42 84 2 pr33644.c:15 (set (reg:SI 3 3 [ D.1244 ])
(reg:SI 3 3 [ D.1244 ])) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(insn_list:REG_LIBCALL 47 (nil))))
(insn 84 44 45 2 pr33644.c:15 (set (reg/f:SI 169)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_EQUAL (plus:SI (reg/f:SI 113 sfp)
(const_int 8 [0x8]))
(nil)))
(insn 45 84 46 2 pr33644.c:15 (set (reg:SI 4 4)
(reg/f:SI 168)) 312 {*movsi_internal1} (expr_list:REG_LIBCALL_ID (const_int 1 [0x1])
(nil)))
When DCE is run during GCSE, insn 44 is being deleted as it is a noop_move_p
and moves REG_LIBCALL note to the following insn (84). But that one doesn't have
REG_LIBCALL_ID note and in this case wasn't even marked, as it is unneeded
and so the next delete_unmarked_insns loop iteration kills even that insn.
This means we end up with a REG_RETVAL note without corresponding RET_LIBCALL
and ICE later on.
I believe it is not a bug to have non-REG_LIBCALL_ID insns within
a libcall sequence as long as they are either useless or something needed
by the libcall sequence insns (i.e. they can be deleted whenever the whole
libcall sequence is killed, but can be also deleted if they are not needed
individually). If so, attached are two possible patches which fix this,
one will move the REG_LIBCALL note to the first insn that is actually not
going to be deleted, the other to the first REG_LIBCALL_ID insn (which is supposed
to be marked by mark_libcall). I prefer the latter patch.
Ok for trunk?
Jakub