This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Your change to jump.c breaks conditional move?
- To: "H.J. Lu" <hjl at lucon dot org>, rth at cygnus dot com
- Subject: Re: Your change to jump.c breaks conditional move?
- From: Richard Henderson <rth at cygnus dot com>
- Date: Thu, 4 Jun 1998 11:14:40 -0700
- Cc: egcs-patches at cygnus dot com, egcs at cygnus dot com
- References: <19980603181400.A9186@dot.cygnus.com> <m0yhbBc-000268C@ocean.lucon.org>
- Reply-To: Richard Henderson <rth at cygnus dot com>
On Thu, Jun 04, 1998 at 07:40:12AM -0700, H.J. Lu wrote:
> > I'll be happy to fix any problems if you can show me an incorrect
> > transformation in any jump pass. But I really suspect things go wrong
> > for you in reload.
Well, I was wrong, the problem isn't in reload. But it isn't in
jump.c either. The lossage is occurring in force_operand.
Given
(plus:SI (reg:SI 3 %ebx)
(symbol_ref/v:SI ("*.LC0")))
force_operand is generating
(insn 169 0 170 (set (reg:SI 55)
(plus:SI (reg:SI 3 %ebx)
(symbol_ref/v:SI ("*.LC0")))) -1 (nil)
(nil))
(insn 170 169 172 (set (reg:SI 54)
(reg:SI 55)) -1 (nil)
(nil))
(insn 172 170 0 (set (reg:SI 53)
(plus:SI (reg:SI 3 %ebx)
(reg:SI 54))) -1 (nil)
(nil))
I'm not sure what the proper thing to do to curtail this lossage,
but the following seems to work.
The generated code is actually pretty ugly. But I think there's
an easy way to fix that up.
r~
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.64
diff -c -p -d -r1.64 expr.c
*** expr.c 1998/06/02 22:48:51 1.64
--- expr.c 1998/06/04 18:12:36
*************** force_operand (value, target)
*** 4526,4532 ****
register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
if (GET_CODE (value) == PLUS)
! binoptab = add_optab;
else if (GET_CODE (value) == MINUS)
binoptab = sub_optab;
else if (GET_CODE (value) == MULT)
--- 4526,4543 ----
register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
if (GET_CODE (value) == PLUS)
! {
! /* Check for a PIC address load. */
! if (flag_pic && XEXP (value, 0) == pic_offset_table_rtx)
! {
! if (!subtarget)
! subtarget = gen_reg_rtx (GET_MODE (value));
! emit_move_insn (subtarget, value);
! return subtarget;
! }
!
! binoptab = add_optab;
! }
else if (GET_CODE (value) == MINUS)
binoptab = sub_optab;
else if (GET_CODE (value) == MULT)
HJ's test case:
#include <stdio.h>
struct foo
{
char buf [256];
int flags;
};
typedef struct foo foo;
void write_int (foo *s, unsigned long long int val)
{
char buf [256];
char *buf_ptr = buf + sizeof (buf);
int len;
int i;
if (s->flags)
{
const char *xdigs = s->flags & 0x1
? "0123456789ABCDEF0X" : "0123456789abcdef0x";
do
{
*--buf_ptr = xdigs[val & 15];
val = val >> 4;
} while (val != 0);
}
else
{
register unsigned int ival = (unsigned int)val;
do
{
*--buf_ptr = (ival % 10) + '0';
ival /= 10;
} while (ival != 0);
}
len = buf + sizeof (buf) - buf_ptr;
for (i = 0; i < len; i++)
s->buf [i] = buf_ptr [i];
}
main ()
{
foo x;
x.flags = -1;
write_int (&x, 0x1234);
printf ("%s\n", x.buf);
}