This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
jump.c/optabs.c bugfix
- To: gcc-patches at gcc dot gnu dot org
- Subject: jump.c/optabs.c bugfix
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Fri, 11 Feb 2000 12:26:57 -0700
- Reply-To: law at cygnus dot com
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);