This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug optimization/12142] New: [hppa-linux, 3.3/3.4 regression] -fnon-call-exceptions generates incorrect code
- From: "tausq at debian dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 2 Sep 2003 22:36:37 -0000
- Subject: [Bug optimization/12142] New: [hppa-linux, 3.3/3.4 regression] -fnon-call-exceptions generates incorrect code
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12142
Summary: [hppa-linux, 3.3/3.4 regression] -fnon-call-exceptions
generates incorrect code
Product: gcc
Version: 3.4
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: tausq at debian dot org
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: hppa-unknown-linux
GCC host triplet: hppa-unknown-linux
GCC target triplet: hppa-unknown-linux
if you compile this code:
=========== bug.cc =============
struct foo
{
void dofoo (const char *) const { }
};
class bar
{
public:
foo *x;
void dobar () { x->dofoo (""); }
};
int main(int argc, char **argv)
{
bar y;
y.dobar ();
return 0;
}
=========== bug.cc =============
with g++ -O1 -fnon-call-exceptions -fPIC -c bug.cc
The resulting assembly looks like this:
Disassembly looks like this:
legolas[23:12] % objdump -drC bug.o
bug.o: file format elf32-hppa-linux
Disassembly of section .text:
00000000 <main>:
0: 4a 94 00 00 ldw 0(r20),r20
0: R_PARISC_DLTIND14R .LC0
4: e8 40 c0 00 bv r0(rp)
8: 34 1c 00 00 ldi 0,ret0
gcc dropped the initialization of 20 so the resulting code does not work
correctly.
According to Dave Anglin:
===========
I've found the bug. It's in count_reg_usage. We have the following rtl:
(insn 27 26 28 0 (set (reg:SI 102)
(plus:SI (reg:SI 19 %r19)
(high:SI (symbol_ref/v/f:SI ("*.LC0") [flags 0x2] <string_cst 0x4021
5420>)))) -1 (nil)
(nil))
(insn 28 27 29 0 (set (reg:SI 102)
(mem/u:SI (lo_sum:SI (reg:SI 102)
(unspec:SI [
(symbol_ref/v/f:SI ("*.LC0") [flags 0x2] <string_cst 0x4
0215420>)
] 0)) [0 S4 A32])) -1 (nil)
(nil))
(insn 29 28 35 0 (set (reg/v/f:SI 101 [ <anonymous> ])
(reg:SI 102)) -1 (nil)
(expr_list:REG_EQUAL (symbol_ref/v/f:SI ("*.LC0") [flags 0x2] <string_cst 0x
40215420>)
(nil)))
The problem occurs in delete_trivially_dead_insn. Reg:SI 102 is dead at
insn 29. The usage count for reg 102 returned by count_reg_usage is 1.
The comment is at the beginning of count_reg_usage says
/* Count the number of times registers are used (not set) in X.
COUNTS is an array in which we accumulate the count, INCR is how much
we count each register usage.
Don't count a usage of DEST, which is the SET_DEST of a SET which
contains X in its SET_SRC. This is because such a SET does not
modify the liveness of DEST. */
Because 102 is used in the dest of insn 28, it's not counted. Thus,
when insn 29 is deleted, the count is reduced to 0. Insn 28 is not
deleted because of the unspec in the mem. However, insn 27 is deleted
because the usage count for reg 102 is 0.
I think the fix is to include the count when doing non-call-exceptions
and the instruction may trap.
===========
This looks like #11975, but actually appears to be a different bug. -fno-gcse
does not have any effect for the above code.