Bug 16836
Summary: | gcc in RC2 miscompiles ia64 toolchain | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | [Retired] Red Hat Linux | Reporter: | Red Hat Bugzilla <bugzilla> | ||||||||
Component: | gcc | Assignee: | Jakub Jelinek <jakub> | ||||||||
Status: | CLOSED CURRENTRELEASE | QA Contact: | |||||||||
Severity: | medium | Docs Contact: | |||||||||
Priority: | medium | ||||||||||
Version: | 7.0 | CC: | jayarhb | ||||||||
Target Milestone: | --- | ||||||||||
Target Release: | --- | ||||||||||
Hardware: | i386 | ||||||||||
OS: | Linux | ||||||||||
URL: | http://gcc.gnu.org/ml/gcc-bugs/2000-08/msg00526.html | ||||||||||
Whiteboard: | |||||||||||
Fixed In Version: | Doc Type: | Bug Fix | |||||||||
Doc Text: | Story Points: | --- | |||||||||
Clone Of: | Environment: | ||||||||||
Last Closed: | 2000-10-03 16:51:06 UTC | Type: | --- | ||||||||
Regression: | --- | Mount Type: | --- | ||||||||
Documentation: | --- | CRM: | |||||||||
Verified Versions: | Category: | --- | |||||||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
Cloudforms Team: | --- | Target Upstream Version: | |||||||||
Embargoed: | |||||||||||
Attachments: |
|
Description
Red Hat Bugzilla
2000-08-23 23:28:02 UTC
Please see testcase at http://gcc.gnu.org/ml/gcc-bugs/2000-08/msg00526.html H.J. Known bug: 32->64 bit cross compilers are broken in the current gcc. 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. 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. I spent an hour to get that testcase. It has only 79 lines -). 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. 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. Created attachment 3122 [details]
We should exclude edx for DImode.
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. Created attachment 3158 [details]
A patch for find_reg ()
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. Created attachment 3178 [details]
An updated patch for find_reg ().
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. |