This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug optimization/12142] New: [hppa-linux, 3.3/3.4 regression] -fnon-call-exceptions generates incorrect code


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]