Bug 12142 - [hppa-linux, 3.3 regression] -fnon-call-exceptions generates incorrect code
Summary: [hppa-linux, 3.3 regression] -fnon-call-exceptions generates incorrect code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2003-09-02 22:36 UTC by Randolph Chung
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: hppa-unknown-linux
Target: hppa-unknown-linux
Build: hppa-unknown-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Randolph Chung 2003-09-02 22:36:31 UTC
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.
Comment 1 GCC Commits 2003-10-08 17:55:51 UTC
Subject: Bug 12142

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	danglin@gcc.gnu.org	2003-10-08 17:55:45

Modified files:
	gcc            : ChangeLog cse.c 
	gcc/config/pa  : pa.c 

Log message:
	PR optimization/12142
	* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
	uses of the register in the SET_SRC.  Remove unnecessary argument.
	* pa.c (legitimize_pic_address): Before reload, use a scratch register
	for the intermediate result in loading the address of a SYMBOL_REF.
	Set the MEM_NOTRAP_P flag for the MEM.  Add a REG_EQUAL to the insn
	which loads the SYMBOL_REF address.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.1337&r2=2.1338
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cse.c.diff?cvsroot=gcc&r1=1.272&r2=1.273
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/pa/pa.c.diff?cvsroot=gcc&r1=1.227&r2=1.228

Comment 2 Andrew Pinski 2003-10-08 18:01:04 UTC
Only a 3.3 regression now.
Comment 3 John David Anglin 2003-10-08 18:51:29 UTC
Do you think 3.3 should be fixed?

I don't really think 3.2 handled -fnon-call-exceptions correctly.
The problem was exposed by a 3.3 change to insn_live_p.  A test
was added to check if an insn might trap when flag_non_call_exceptions
is true.

As far as the PA goes, this was needed for libjava.  We still don't
have libffi, needed for libjava, integrated yet.

Comment 4 Andrew Pinski 2003-10-08 21:31:35 UTC
Closing as fixed as the maintainer of HPPA does not think this should be fixed for 3.3.x.  Also does 
this patch fix PR 11975?
Comment 5 GCC Commits 2004-06-11 17:27:14 UTC
Subject: Bug 12142

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	sh-elf-3_5-branch
Changes by:	amylaar@gcc.gnu.org	2004-06-11 17:27:11

Modified files:
	gcc            : ChangeLog.sh-elf cse.c 

Log message:
	Back out this patch:
	2003-10-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
	PR optimization/12142
	* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
	uses of the register in the SET_SRC.  Remove unnecessary argument.
	
	Replace it with this:
	* cse.c (count_reg_usage): In INSN, JUMP_INSN and CALL_INSN cases,
	if flag_non_call_exceptions is set and the insn may trap, pass
	pc_rtx as dest for recursion.
	In SET_SRC part of SET case, if dest is already set, pass it down
	unchanged.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.sh-elf.diff?cvsroot=gcc&only_with_tag=sh-elf-3_5-branch&r1=1.1.2.7&r2=1.1.2.8
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cse.c.diff?cvsroot=gcc&only_with_tag=sh-elf-3_5-branch&r1=1.301&r2=1.301.2.1

Comment 6 GCC Commits 2005-07-18 14:57:23 UTC
Subject: Bug 12142

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	sh-elf-4_1-branch
Changes by:	amylaar@gcc.gnu.org	2005-07-18 14:57:06

Modified files:
	gcc            : ChangeLog loop.c cse.c calls.c ifcvt.c 

Log message:
	2005-07-15  J"orn Rennecke <joern.rennecke@st.com>
	
	cvs update -j1.531 -j1.530 loop.c
	Re-apply this patch:
	2005-05-30  Pat Haugen  <pthaugen@us.ibm.com>
	* loop.c (loop_invariant_p, valid_initial_value_p): Use
	regs_invalidated_by_call instead of call_used_regs.
	
	2005-07-15  J"orn Rennecke <joern.rennecke@superh.com>
	
	PR rtl-optimization/18992
	http://gcc.gnu.org/ml/gcc-patches/2005-07/msg01140.html
	Back out this patch:
	2003-10-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
	PR optimization/12142
	* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
	uses of the register in the SET_SRC.  Remove unnecessary argument.
	
	Replace it with this:
	* cse.c (count_reg_usage): In INSN, JUMP_INSN and CALL_INSN cases,
	if flag_non_call_exceptions is set and the insn may trap, pass
	pc_rtx as dest for recursion.
	In SET_SRC part of SET case, if dest is already set, pass it down
	unchanged.
	
	2005-07-15  J"orn Rennecke <joern.rennecke@superh.com>
	
	PR rtl-optimization/21848
	http://gcc.gnu.org/ml/gcc-patches/2005-07/msg01142.html
	* calls.c (emit_library_call_value_1): For const functions, add
	USEs of the stack slots to CALL_INSN_FUNCTION_USAGE.
	
	2005-07-15  J"orn Rennecke <joern.rennecke@superh.com>
	
	PR rtl-optimization/20370
	http://gcc.gnu.org/ml/gcc-patches/2005-07/msg01148.html
	* ifcvt.c (dead_or_predicable): Before calling propagate_block,
	call allocate_reg_info if necessary.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=sh-elf-4_1-branch&r1=2.8142.2.23&r2=2.8142.2.24
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/loop.c.diff?cvsroot=gcc&only_with_tag=sh-elf-4_1-branch&r1=1.525.2.2&r2=1.525.2.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cse.c.diff?cvsroot=gcc&only_with_tag=sh-elf-4_1-branch&r1=1.351.2.1&r2=1.351.2.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/calls.c.diff?cvsroot=gcc&only_with_tag=sh-elf-4_1-branch&r1=1.385.2.1&r2=1.385.2.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ifcvt.c.diff?cvsroot=gcc&only_with_tag=sh-elf-4_1-branch&r1=1.184.2.2&r2=1.184.2.3

Comment 7 GCC Commits 2005-07-28 11:56:15 UTC
Subject: Bug 12142

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	amylaar@gcc.gnu.org	2005-07-28 11:55:58

Modified files:
	gcc            : ChangeLog cse.c 

Log message:
	PR rtl-optimization/18992
	Back out this patch:
	2003-10-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
	PR optimization/12142
	* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
	uses of the register in the SET_SRC.  Remove unnecessary argument.
	
	Replace it with this:
	* cse.c (count_reg_usage): In INSN, JUMP_INSN and CALL_INSN cases,
	if flag_non_call_exceptions is set and the insn may trap, pass
	pc_rtx as dest for recursion.
	In SET_SRC part of SET case, if dest is already set, pass it down
	unchanged.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9579&r2=2.9580
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cse.c.diff?cvsroot=gcc&r1=1.357&r2=1.358