Bug 16836 - gcc in RC2 miscompiles ia64 toolchain
gcc in RC2 miscompiles ia64 toolchain
Status: CLOSED CURRENTRELEASE
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
http://gcc.gnu.org/ml/gcc-bugs/2000-0...
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2000-08-23 19:28 EDT by Red Hat Bugzilla
Modified: 2008-05-01 11:37 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2000-10-03 12:51:06 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
We should exclude edx for DImode. (653 bytes, patch)
2000-08-31 11:54 EDT, Red Hat Bugzilla
no flags Details | Diff
A patch for find_reg () (1.73 KB, patch)
2000-08-31 20:24 EDT, Red Hat Bugzilla
no flags Details | Diff
An updated patch for find_reg (). (1.98 KB, patch)
2000-09-01 10:58 EDT, Red Hat Bugzilla
no flags Details | Diff

  None (edit)
Description Red Hat Bugzilla 2000-08-23 19:28:02 EDT
gcc in RC2 miscompiles ia64 0814 toolchain under ia32 with -O2 -fPIC.
assign_file_positions_for_segments () in bfd/elf.c from ia64 0814
toolchain is miscompiled. Around line 2875:

          if (p->p_type == PT_LOAD)
            {
              bfd_signed_vma adjust; 

              if ((flags & SEC_LOAD) != 0)
                {
                  adjust = sec->lma - (p->p_paddr + p->p_memsz);
                  if (adjust < 0)
                    adjust = 0;
                }
              else if ((flags & SEC_ALLOC) != 0)
                {
                  /* The section VMA must equal the file position
                     modulo the page size.  FIXME: I'm not sure if 
                     this adjustment is really necessary.  We used to 
                     not have the SEC_LOAD case just above, and then
                     this was necessary, but now I'm not sure.  */
                  if ((abfd->flags & D_PAGED) != 0)
                    adjust = (sec->vma - voff) % bed->maxpagesize;
                  else
                    adjust = (sec->vma - voff) % align;
                }
              else
               adjust = 0;

              if (adjust != 0)
                {
                  if (i == 0)
                    {
                      (* _bfd_error_handler)
                        (_("Error: First section in segment (%s) starts at
0x%x"),
                         bfd_section_name (abfd, sec), sec->lma);
                      (* _bfd_error_handler)
                        (_("       whereas segment starts at 0x%x"),
                         p->p_paddr);

                      return false;
                    }

The line:

	adjust = sec->lma - (p->p_paddr + p->p_memsz);

should set adjust to 0 if sec->lma == (p->p_paddr + p->p_memsz). However,
with -O2 -fPIC, it is set to sec->lma. As the result, I got

lt-ld-new: Error: First section in segment (.interp) starts at 0x1c8
lt-ld-new:        whereas segment starts at 0x0

Compile with -O -fPIC or -O2 generates the corrent code. I couldn't
find the smaller testcase.

H.J.
Comment 1 Red Hat Bugzilla 2000-08-23 22:49:55 EDT
Please see testcase at

http://gcc.gnu.org/ml/gcc-bugs/2000-08/msg00526.html

H.J.
Comment 2 Red Hat Bugzilla 2000-08-24 19:33:39 EDT
Known bug: 32->64 bit cross compilers are broken in the
current gcc.
Comment 3 Red Hat Bugzilla 2000-08-24 19:39:27 EDT
Please see my testcase. It has very little to do with cross compiler.
It is long long what is broken with -O2 -fPIC.

H.J.
Comment 4 Red Hat Bugzilla 2000-08-25 00:48:06 EDT
H.J. is right, this is serious problem in reload. I have spent some time
on it yesterday, but haven't figured out where the bug is yet.
BTW: The testcase can be trimmed down a little bit and -fpic is only
interesting to it because it makes %ebx a fixed register, thus increasing
register pressure.
Comment 5 Red Hat Bugzilla 2000-08-25 12:45:43 EDT
I spent an hour to get that testcase. It has only 79 lines -).
Comment 6 Red Hat Bugzilla 2000-08-30 18:35:02 EDT
I don't think this is a reload problem. I tracked it down to
try_split (). Given an RTL

(insn 83 291 254 (parallel[ 
            (set (reg:DI 0 eax)
                (plus:DI (reg:DI 0 eax)
                    (mem/s:DI (plus:SI (reg:SI 2 ecx)
                            (const_int 20 [0x14])) 10)))
            (clobber (reg:CC 17 flags))
        ] ) 108 {adddi3} (nil)
    (nil))

to

(sequence[ 
        (insn 292 0 293 (parallel[ 
                    (set (reg:CC 17 flags)
                        (plus:CC (reg:SI 0 eax)
                            (mem/s:SI (plus:SI (reg:SI 2 ecx)
                                    (const_int 20 [0x14])) 10)))
                    (set (reg:SI 0 eax)
                        (plus:SI (reg:SI 0 eax)
                            (mem/s:SI (plus:SI (reg:SI 2 ecx)
                                    (const_int 20 [0x14])) 10)))
                ] ) -1 (nil)
            (nil))
        (insn 293 292 0 (parallel[ 
                    (set (reg:SI 1 edx)
                        (plus:SI (reg:SI 1 edx)
                            (plus:SI (mem/s:SI (plus:SI (reg:SI 2 ecx)
                                        (const_int 24 [0x18])) 10)
                                (ltu:SI (reg:CC 17 flags)
                                    (const_int 0 [0x0])))))
                    (clobber (reg:CC 17 flags))
                ] ) -1 (nil)
            (nil))
    ] )

The problem is edx is used in

(insn 294 257 295 (set (reg:SI 1 edx)
        (mem/s:SI (reg:SI 4 esi) 10)) -1 (nil)
    (nil))  

a few instructiions down. As the result, the second part of the sequence
gets deleted later since edx is dead.


H.J.
Comment 7 Red Hat Bugzilla 2000-08-30 22:48:46 EDT
You are right. It is a reload bug. I don't think reload knows

(reg/v:DI 1 edx) == (reg:DI 0 eax))

It turns

(insn 86 257 87 (parallel[ 
            (set (reg/v:DI 1 edx)
                (minus:DI (mem/s:DI (reg/v:SI 43) 10)
                    (reg:DI 0 eax)))
            (clobber (reg:CC 17 flags))
        ] ) 129 {subdi3} (insn_list 83 (nil))
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_DEAD (reg:DI 0 eax)
            (nil))))

into

(insn 257 85 260 (set (reg:SI 4 esi)
        (reg/v:SI 43)) -1 (nil)
    (nil))

(insn 260 257 86 (set (reg/v:DI 1 edx)
        (mem/s:DI (reg/v:SI 43) 10)) -1 (nil)
    (nil))

(insn 86 260 87 (parallel[ 
            (set (reg/v:DI 1 edx)
                (minus:DI (mem/s:DI (reg/v:SI 43) 10)
                    (reg:DI 0 eax)))
            (clobber (reg:CC 17 flags))
        ] ) 129 {subdi3} (insn_list 83 (nil))
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_DEAD (reg:DI 0 eax)
            (nil))))

From then on, everything goes downhill. I will take another look
tomorror.
Comment 8 Red Hat Bugzilla 2000-08-31 11:54:17 EDT
Created attachment 3122 [details]
We should exclude edx for DImode.
Comment 9 Red Hat Bugzilla 2000-08-31 11:57:55 EDT
Jakub, what do you think my patch? The problem is we cannot allocate edx
for DImode since eax/edx is a fixed pair for DImode. When we allocate
eax for DImode, we have implicitly allocated edx together with eax for DImode.
I don't know how to express it. That is what I came up with. There must be
a better fix.
Comment 10 Red Hat Bugzilla 2000-08-31 20:24:05 EDT
Created attachment 3158 [details]
A patch for find_reg ()
Comment 11 Red Hat Bugzilla 2000-08-31 20:29:27 EDT
Jakub, what do you think my new patch? The problem is
global_conflicts () is called before find_reg (). It
misses the hard register conflicts introduced by find_reg ().
I don't know if my patch is correct or not.
Comment 12 Red Hat Bugzilla 2000-09-01 10:58:08 EDT
Created attachment 3178 [details]
An updated patch for find_reg ().
Comment 13 Red Hat Bugzilla 2000-09-01 11:00:49 EDT
I updated my patch. I changed

if (reg && r >= 0 && r != regno && TEST_HARD_REG_BIT (used, r))

to

if (reg && r >= 0 && r < regno && TEST_HARD_REG_BIT (used, r))

since a hard register r >= regno won't overlap with regno.

Note You need to log in before you can comment on or make changes to this bug.