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]

[3.3/3.4/3.5 PATCH] Fix PR 12147 (reload bug)


Hello,

this fixes PR 12147, which is caused by a bug in reload_reg_free_p
(reload1.c) that allowed the same register to be used for both a
RELOAD_OTHER and a RELOAD_FOR_OPADDR_ADDR reload.  As the live 
ranges of these two types overlap, this is broken.

By inspection I've also found a similar bug in reload_reg_reaches_end_p:
a register used for a RELOAD_FOR_OTHER_ADDRESS can later be used for
a RELOAD_FOR_OPADDR_ADDR reload, in which case the value doesn't
reach the end of the insn.

As typical for reload, this is reproducible only with a rather
large test case, and only on the 3.3 branch.  However, the bug
is latently present on all branches (and for all targets),
thus I'd propose to apply the patch on 3.3, 3.4, and mainline.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux
on the 3.3 branch, 3.4 branch and mainline.

OK for 3.3/3.4/mainline?

Bye,
Ulrich

ChangeLog:

	PR optimization/12147
	* reload1.c (reload_reg_free_p): RELOAD_OTHER conflicts with
	RELOAD_FOR_OPADDR_ADDR.
	(reload_reg_reaches_end_p): A RELOAD_FOR_OTHER_ADDRESS register
	might be reused as RELOAD_FOR_OPADDR_ADDR register.


Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.420
diff -c -p -r1.420 reload1.c
*** gcc/reload1.c	17 Jan 2004 22:14:17 -0000	1.420
--- gcc/reload1.c	22 Jan 2004 20:34:26 -0000
*************** reload_reg_free_p (unsigned int regno, i
*** 4316,4321 ****
--- 4316,4322 ----
        /* In use for anything means we can't use it for RELOAD_OTHER.  */
        if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
  	  || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+ 	  || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
  	  || TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
  	return 0;
  
*************** reload_reg_reaches_end_p (unsigned int r
*** 4494,4499 ****
--- 4495,4501 ----
  	  return 0;
  
        return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+ 	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
  	      && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
  	      && ! TEST_HARD_REG_BIT (reload_reg_used, regno));
  
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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