This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] reload fix?
- From: Glen Nakamura <glen at imodulo dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 Mar 2003 23:23:52 -1000
- Subject: [PATCH] reload fix?
Aloha,
I did some analysis of the gcc.c-torture/execute/20000605-1.c execution
testsuite failures on alphaev56-pc-linux-gnu for the 3.3 branch.
The problem was that GCC reloaded (SUBREG:SI (REG:DI INT_REG) 0)
into (REG:SI FLOAT_REG) during the global allocation pass,
but the contents of the float register was really DImode. This doesn't
work properly because SImode integers are _not_ represented by
the low order bits of a DImode integer when stored in a float register.
In this particular case: (REG:DI FLOAT_REG) == 1, but (REG:SI FLOAT_REG) != 1
when FLOAT_REG contains the 0x0000000000000001 bit pattern.
Aftering some searching, I found a suspicious conditional in choose_reload_regs
which allowed a mode change even though REG_CANNOT_CHANGE_MODE_P returned true.
I think && instead of || makes sense here:
(bootstrapped and regtested on alphaev56-pc-linux-gnu 3.3 branch)
2003-03-12 Glen Nakamura <glen at imodulo dot com>
* reload1.c (choose_reload_regs): Use && instead of ||
with REG_CANNOT_CHANGE_MODE_P condition.
diff -Nru3p gcc-3.3.orig/gcc/reload1.c gcc-3.3/gcc/reload1.c
--- gcc-3.3.orig/gcc/reload1.c 2003-02-15 23:35:45.000000000 +0000
+++ gcc-3.3/gcc/reload1.c 2003-02-15 23:35:45.000000000 +0000
@@ -5493,7 +5493,7 @@ choose_reload_regs (chain)
#ifdef CANNOT_CHANGE_MODE_CLASS
(!REG_CANNOT_CHANGE_MODE_P (i, GET_MODE (last_reg),
need_mode)
- ||
+ &&
#endif
(GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))