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] Correctly determine implicit sets in postreload


This bug was uncovered while trying to get gcc to bootstrap targeting
the Thumb instruction set on ARM.

The Thumb compiler has a condjump instruction of the form

(define_insn "cbranchsi4_scratch"
  [(set (pc) (if_then_else
	      (match_operator 4 "arm_comparison_operator"
	       [(match_operand:SI 1 "s_register_operand" "l,0")
	        (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
	      (label_ref (match_operand 3 "" ""))
	      (pc)))
   (clobber (match_scratch:SI 0 "=l,l"))]

which can be used to compare and branch using some constants that aren't
available for the normal cmp instruction (which doesn't take negative
values).

However, this pattern matches onlyjump_p because it has exactly one set
of the PC.

We've been using onlyjump_p in reload_cse_move2add to determine if we
could extract an implicit set from a jump instruction, but we were
missing the fact that the clobber might alter the value we had.

The patch below fixes this by removing onlyjump_p from the guarding
condition, but then verifying that the register in the comparison isn't
modified elsewhere in the pattern.

An added benefit of this change is that we can now extract an implicit
set from condjumps with real side-effects, such as

(parallel [(set (pc) (if_then_else
			(ne (reg X) (const_int 0))
			(label)
			(pc)))
	   (set (reg Y) (reg X))])

which copies X into Y and branches if the result was non-zero (so we
know X is zero if the branch wasn't taken).

Bootstrapped on arm-netbsd targeting the Thumb instruction set.

2004-08-20  Richard Earnshaw  <rearnsha@arm.com>

	* postreload.c (reload_cse_move2add): Allow any condjump, but check
	that the implicit set isn't clobbered in the jump insn.


Index: postreload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/postreload.c,v
retrieving revision 2.19
diff -p -r2.19 postreload.c
*** postreload.c	18 Aug 2004 17:04:59 -0000	2.19
--- postreload.c	20 Aug 2004 09:57:19 -0000
*************** reload_cse_move2add (rtx first)
*** 1375,1387 ****
  
        /* If INSN is a conditional branch, we try to extract an
  	 implicit set out of it.  */
!       if (any_condjump_p (insn) && onlyjump_p (insn))
  	{
  	  rtx cnd = fis_get_condition (insn);
  
  	  if (cnd != NULL_RTX
  	      && GET_CODE (cnd) == NE
  	      && REG_P (XEXP (cnd, 0))
  	      /* The following two checks, which are also in
  		 move2add_note_store, are intended to reduce the
  		 number of calls to gen_rtx_SET to avoid memory
--- 1375,1388 ----
  
        /* If INSN is a conditional branch, we try to extract an
  	 implicit set out of it.  */
!       if (any_condjump_p (insn))
  	{
  	  rtx cnd = fis_get_condition (insn);
  
  	  if (cnd != NULL_RTX
  	      && GET_CODE (cnd) == NE
  	      && REG_P (XEXP (cnd, 0))
+ 	      && !reg_set_p (XEXP (cnd, 0), insn)
  	      /* The following two checks, which are also in
  		 move2add_note_store, are intended to reduce the
  		 number of calls to gen_rtx_SET to avoid memory

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