This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/45312] [4.4 Regression] GCC 4.4.4 miscompiles the Linux kernel
- From: "vmakarov at redhat dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 3 Sep 2010 20:45:29 -0000
- Subject: [Bug middle-end/45312] [4.4 Regression] GCC 4.4.4 miscompiles the Linux kernel
- References: <bug-45312-5637@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #15 from vmakarov at redhat dot com 2010-09-03 20:45 -------
(In reply to comment #14)
Ulrih, I've just wanted to post the following when I found that you already
posted analogous conclusion. I should have been on CC to see your comment
right away. The problem is really fundamental. Code for
merge_assigned_reloads ignores inheritance (and dependencies between reloads
because of inheritance) at all. Here is my post wanted to add.
After thorough examining code for inheritance in
reload1.c::choose_reload_regs, I can not find where it can be wrong
for this test case. After this function, we have the following
reloads:
Reload 0: reload_in (SI) = (reg/v/f:SI 132 [ kpte ])
GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
Reload 1: reload_in (SI) = (reg/v/f:SI 132 [ kpte ])
DIREG, RELOAD_FOR_INPUT (opnum = 1)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
Reload 2: reload_in (SI) = (reg:SI 600 [ D.29693 ])
BREG, RELOAD_FOR_INPUT (opnum = 2)
reload_in_reg: (reg:SI 600 [ D.29693 ])
Reload 3: reload_in (SI) = (reg:SI 356)
CREG, RELOAD_FOR_INPUT (opnum = 3)
reload_in_reg: (reg:SI 356)
Function reload1.c::merge_assigned_reload called after
reload1.c::choose_reload_regs for targets with SMALL_REGISTER_CLASSES
(i686 case) merges 0th and 1st reloads (merging results in nullifying
reload_in in 1st the reload and changing 0th to RELOAD_OTHER)
producing
Reload 0: reload_in (SI) = (reg/v/f:SI 132 [ kpte ])
GENERAL_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
reload_reg_rtx: (reg:SI 5 di)
Reload 1: DIREG, RELOAD_FOR_INPUT (opnum = 1)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
reload_reg_rtx: (reg:SI 5 di)
Reload 2: reload_in (SI) = (reg:SI 2 cx [501])
BREG, RELOAD_FOR_INPUT (opnum = 2)
reload_in_reg: (reg:SI 600 [ D.29693 ])
reload_reg_rtx: (reg:SI 3 bx)
Reload 3: reload_in (SI) = (reg:SI 356)
CREG, RELOAD_FOR_INPUT (opnum = 3)
reload_in_reg: (reg:SI 356)
reload_reg_rtx: (reg:SI 2 cx)
So far everything is ok. But after that, it changes 3rd reload to
RELOAD_OTHER which means that it will be issued before 2nd reload
instead of after it as it was before. Changing to RELOAD_OTHER is
done because the code assumes (on function
reg_overlap_mentioned_for_reload_p) that changing 3rd reload will
affect 0th reload. In this unfortunate case pseudo 132 (from 0th
reload) and pseudo 356 (from 3rd reload) have equivalent memory and
reg_overlap_mentioned_for_reload_p is a simplified code which in this
case decides that changing equivalent memory of p356 affects
equivalent memory of p132.
Reload 0: reload_in (SI) = (reg/v/f:SI 132 [ kpte ])
GENERAL_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
reload_reg_rtx: (reg:SI 5 di)
Reload 1: DIREG, RELOAD_FOR_INPUT (opnum = 1)
reload_in_reg: (reg/v/f:SI 132 [ kpte ])
reload_reg_rtx: (reg:SI 5 di)
Reload 2: reload_in (SI) = (reg:SI 2 cx [501])
BREG, RELOAD_FOR_INPUT (opnum = 2)
reload_in_reg: (reg:SI 600 [ D.29693 ])
reload_reg_rtx: (reg:SI 3 bx)
Reload 3: reload_in (SI) = (reg:SI 356)
CREG, RELOAD_OTHER (opnum = 3)
reload_in_reg: (reg:SI 356)
reload_reg_rtx: (reg:SI 2 cx)
I don't see a good and simple fix for general case (just fixing
reg_overlap_mentioned_for_reload_p would wrong and dangerous) for this
code when inheritance is used and there are dependencies for reload 2
and 3 in this case.
--
vmakarov at redhat dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |vmakarov at redhat dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45312