This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] Correct big-endian problem in emit_group_store
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Eric Botcazou <ebotcazou at libertysurf dot fr>
- Date: Wed, 12 Apr 2006 07:22:52 -0600 (MDT)
- Subject: [Committed] Correct big-endian problem in emit_group_store
The following patch corrects an endianess bug in my recent change to
emit_group_store, diagnosed by Eric Botcazou. The problem is a mistake
in the logic, where when calling subreg_low_part offset, the arguments
require the narrow mode to come before the wide mode, matching the
outer/inner modes of a SUBREG. For this optimization of PARALLELs,
the sense of inner and outer is reversed.
The following correction has been tested on i686-pc-linux-gnu and
powerpc-linux-gnu with a full "make bootstrap", and regression
tested with a top-level "make -k check". I've confirmed that
PR17959 is still resolved, but it looks like poor register allocation
(or a missing peephole2?) generates slightly worse code than before.
Before my original patch we required 4 insns, after my original patch
we required 2, with this correctness fix we now require 3. I'll see
what I can do, but the initial RTL looks good.
Committed to mainline as 112887.
2006-04-11 Roger Sayle <roger@eyesopen.com>
* expr.c (emit_group_store): Correct operand order in call to
subreg_lowpart_offset. Always create paradoxical SUBREGs with
a SUBREG_BYTE of zero.
Index: expr.c
===================================================================
*** expr.c (revision 112817)
--- expr.c (working copy)
*************** emit_group_store (rtx orig_dst, rtx src,
*** 1940,1950 ****
if (start < finish)
{
inner = GET_MODE (tmps[start]);
! bytepos = subreg_lowpart_offset (outer, inner);
if (INTVAL (XEXP (XVECEXP (src, 0, start), 1)) == bytepos)
{
temp = simplify_gen_subreg (outer, tmps[start],
! inner, bytepos);
if (temp)
{
emit_move_insn (dst, temp);
--- 1940,1950 ----
if (start < finish)
{
inner = GET_MODE (tmps[start]);
! bytepos = subreg_lowpart_offset (inner, outer);
if (INTVAL (XEXP (XVECEXP (src, 0, start), 1)) == bytepos)
{
temp = simplify_gen_subreg (outer, tmps[start],
! inner, 0);
if (temp)
{
emit_move_insn (dst, temp);
*************** emit_group_store (rtx orig_dst, rtx src,
*** 1959,1969 ****
&& start < finish - 1)
{
inner = GET_MODE (tmps[finish - 1]);
! bytepos = subreg_lowpart_offset (outer, inner);
if (INTVAL (XEXP (XVECEXP (src, 0, finish - 1), 1)) == bytepos)
{
temp = simplify_gen_subreg (outer, tmps[finish - 1],
! inner, bytepos);
if (temp)
{
emit_move_insn (dst, temp);
--- 1959,1969 ----
&& start < finish - 1)
{
inner = GET_MODE (tmps[finish - 1]);
! bytepos = subreg_lowpart_offset (inner, outer);
if (INTVAL (XEXP (XVECEXP (src, 0, finish - 1), 1)) == bytepos)
{
temp = simplify_gen_subreg (outer, tmps[finish - 1],
! inner, 0);
if (temp)
{
emit_move_insn (dst, temp);
Roger
--