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] Fix reload ICE with swapped operands


Hello,

Andreas' new regression tester has revealed a latent bug in
find_reloads, which causes test case failures on s390-ibm-linux
when building the compiler with --enable-checking=release.

The problem shows up with my *cmpsi_cct pattern, which reads
  [(set (reg 33)
        (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,Q")
                 (match_operand:SI 1 "general_operand" "d,K,R,T,BQ")))]

Note that Q is an EXTRA_MEMORY_CONSTRAINT, while BQ is a two-letter
EXTRA_CONSTRAINT.  Both accept memory operands without an index register;
BQ in addition rejects constant pool references.

Now assume we get here in find_reloads with the first operand a MEM
with invalid address, and the second operand a MEM with valid address
but with index register.  Before considering alternatives, find_reload
will notice that the first operand requires an address reload.  It will
push the corresponding reloads, and set address_reloaded[0] to true.

Since address_reloaded[0] is true, operand 0 will fulfil the 'Q' 
constraint.  But as operand 1 has an index register, it won't
fultil 'BQ', and since BQ is not an EXTRA_MEMORY_CONSTRAINT, 
find_reload gives up on this alternative.

So it will find no alternative that wins without reload.  However,
as the insn has a '%' marker, it will now try again with operands
0 and 1 swapped.  The way this works is by swapping in-place the
find_reloads data structures corresponding to the two operands.

Unfortunately, the address_reloads array is *not* swapped here.
Thus in the next pass through the alternatives list, the (now)
operand 0 of the form 'mem (base + index)' will get accepted,
because address_reloaded[0] is still true, even though the new
operand 0 did *not* have its address reloaded ...

The patch below fixes the problem by swapping address_reloaded
at the same place preferred_class and pref_or_nothing are already
swapped.  (It looks like none of the other per-operand arrays in
find_reloads need to be swapped; but the whole things appears 
somewhat fragile to me ...)

Bootstrapped/regtested on s390-ibm-linux, s390x-ibm-linux, and
i386-pc-linux.  OK for mainline?

Bye,
Ulrich


ChangeLog:

	* reload.c (find_reloads): Swap address_reloaded flags when
	swapping commutative operands.


Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.265
diff -c -p -r1.265 reload.c
*** gcc/reload.c	15 Jan 2005 16:06:15 -0000	1.265
--- gcc/reload.c	22 Jan 2005 19:47:09 -0000
*************** find_reloads (rtx insn, int replace, int
*** 3668,3673 ****
--- 3668,3677 ----
  	  pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
  	  pref_or_nothing[commutative + 1] = t;
  
+ 	  t = address_reloaded[commutative];
+ 	  address_reloaded[commutative] = address_reloaded[commutative + 1];
+ 	  address_reloaded[commutative + 1] = t;
+ 
  	  memcpy (constraints, recog_data.constraints,
  		  noperands * sizeof (char *));
  	  goto try_swapped;
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com


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