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]

jump.c/optabs.c bugfix



On the PA (and possibly other ports) a compare/relational expression can
have a CONST_INT as its first operand.  ie something like this is valid

(lt (const_int 0) (reg X)

jump.c assumes that can't happen when converting a multi-insn sequence
into a conditional move.

It's even possible due to our model of having a pass optimize one style
of code, then let another pass clean it up we can even get stuff like

(lt (const_int 0) (const_int -1))

Which we expect later passes to optimize into a compile time constant value.

However, optabs.c::emit_conditional_move assumes such relationals never
occur:

  /* Everything should now be in the suitable form, so emit the compare insn
     and then the conditional move.  */

  comparison
    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);

  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
  if (GET_CODE (comparison) != code)
    /* This shouldn't happen.  */
    abort ();

op0 would be (const_int 0), op1 would be (const_int -1).  compare_from_rtx
would realize the result of the relational is a compile time constant and
return const_false_rtx which triggers the abort.

Needless to say I'm bringing this up because it actually happened :-)  My
testcase does not trigger in the mainline sources, but the underlying
problems remain and are addressed by the attached patch.

	* jump.c (jump_optimize_1): The first operand in a relational
	can be a CONST_INT.
	* optabs.c (emit_conditional_move): Handle relationals which
	have a known true/false result.

Index: jump.c
===================================================================
RCS file: /cvs/cvsfiles/devo//gcc/jump.c,v
retrieving revision 1.156
diff -c -3 -p -r1.156 jump.c
*** jump.c	1999/09/07 04:13:46	1.156
--- jump.c	2000/02/11 18:12:31
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1074,1083 ****
  		   insn?  After all, we're going to delete it.  We'd have
  		   to modify emit_conditional_move to take a comparison rtx
  		   instead or write a new function.  */
! 		cond0 = gen_reg_rtx (GET_MODE (XEXP (temp4, 0)));
  		/* We want the target to be able to simplify comparisons with
  		   zero (and maybe other constants as well), so don't create
  		   pseudos for them.  There's no need to either.  */
  		if (GET_CODE (XEXP (temp4, 1)) == CONST_INT
  		    || GET_CODE (XEXP (temp4, 1)) == CONST_DOUBLE)
  		  cond1 = XEXP (temp4, 1);
--- 1074,1089 ----
  		   insn?  After all, we're going to delete it.  We'd have
  		   to modify emit_conditional_move to take a comparison rtx
  		   instead or write a new function.  */
! 
  		/* We want the target to be able to simplify comparisons with
  		   zero (and maybe other constants as well), so don't create
  		   pseudos for them.  There's no need to either.  */
+ 		if (GET_CODE (XEXP (temp4, 0)) == CONST_INT
+ 		    || GET_CODE (XEXP (temp4, 0)) == CONST_DOUBLE)
+ 		  cond0 = XEXP (temp4, 0);
+ 		else
+ 		  cond0 = gen_reg_rtx (GET_MODE (XEXP (temp4, 0)));
+ 
  		if (GET_CODE (XEXP (temp4, 1)) == CONST_INT
  		    || GET_CODE (XEXP (temp4, 1)) == CONST_DOUBLE)
  		  cond1 = XEXP (temp4, 1);
Index: optabs.c
===================================================================
RCS file: /cvs/cvsfiles/devo//gcc/optabs.c,v
retrieving revision 1.119
diff -c -3 -p -r1.119 optabs.c
*** optabs.c	1999/09/14 02:21:55	1.119
--- optabs.c	2000/02/11 18:12:39
*************** emit_conditional_move (target, code, op0
*** 3521,3529 ****
      = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
  
    /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
    if (GET_CODE (comparison) != code)
!     /* This shouldn't happen.  */
!     abort ();
    
    insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
  
--- 3521,3531 ----
      = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
  
    /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
+   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
+      return NULL and let the caller figure out how best to deal with this
+      situation.  */
    if (GET_CODE (comparison) != code)
!     return NULL_RTX;
    
    insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
  






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