This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]