Commit 230dedb3 by Jan Hubicka Committed by Jan Hubicka

expr.c (expand_expr_real_1): <MAX_EXPR, MIN_EXPR>: Canonicalize to compare against 0 when possible.

	* expr.c (expand_expr_real_1): <MAX_EXPR, MIN_EXPR>: Canonicalize
	to compare against 0 when possible.
	* gcc.target/i386/minmax-1.c: New.
	* gcc.target/i386/minmax-2.c: New.

From-SVN: r106827
parent df259245
2005-11-12 Jan Hubicka <jh@suse.cz>
* expr.c (expand_expr_real_1): <MAX_EXPR, MIN_EXPR>: Canonicalize
to compare against 0 when possible.
2005-11-12 Jie Zhang <jie.zhang@analog.com> 2005-11-12 Jie Zhang <jie.zhang@analog.com>
* config/bfin/bfin.h (REGISTER_NAMES, SHORT_REGISTER_NAMES, * config/bfin/bfin.h (REGISTER_NAMES, SHORT_REGISTER_NAMES,
......
...@@ -8020,69 +8020,92 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -8020,69 +8020,92 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (! CONSTANT_P (op1)) if (! CONSTANT_P (op1))
op1 = force_reg (mode, op1); op1 = force_reg (mode, op1);
#ifdef HAVE_conditional_move {
/* Use a conditional move if possible. */ enum rtx_code comparison_code;
if (can_conditionally_move_p (mode)) rtx cmpop1 = op1;
{
enum rtx_code comparison_code;
rtx insn;
if (code == MAX_EXPR) if (code == MAX_EXPR)
comparison_code = unsignedp ? GEU : GE; comparison_code = unsignedp ? GEU : GE;
else else
comparison_code = unsignedp ? LEU : LE; comparison_code = unsignedp ? LEU : LE;
/* ??? Same problem as in expmed.c: emit_conditional_move /* Canonicalize to comparsions against 0. */
forces a stack adjustment via compare_from_rtx, and we if (op1 == const1_rtx)
lose the stack adjustment if the sequence we are about {
to create is discarded. */ /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
do_pending_stack_adjust (); or (a != 0 ? a : 1) for unsigned.
For MIN we are safe converting (a <= 1 ? a : 1)
into (a <= 0 ? a : 1) */
cmpop1 = const0_rtx;
if (code == MAX_EXPR)
comparison_code = unsignedp ? NE : GT;
}
if (op1 == constm1_rtx && !unsignedp)
{
/* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
cmpop1 = const0_rtx;
if (code == MIN_EXPR)
comparison_code = LT;
}
#ifdef HAVE_conditional_move
/* Use a conditional move if possible. */
if (can_conditionally_move_p (mode))
{
rtx insn;
start_sequence (); /* ??? Same problem as in expmed.c: emit_conditional_move
forces a stack adjustment via compare_from_rtx, and we
lose the stack adjustment if the sequence we are about
to create is discarded. */
do_pending_stack_adjust ();
/* Try to emit the conditional move. */ start_sequence ();
insn = emit_conditional_move (target, comparison_code,
op0, op1, mode,
op0, op1, mode,
unsignedp);
/* If we could do the conditional move, emit the sequence, /* Try to emit the conditional move. */
and return. */ insn = emit_conditional_move (target, comparison_code,
if (insn) op0, cmpop1, mode,
{ op0, op1, mode,
rtx seq = get_insns (); unsignedp);
end_sequence ();
emit_insn (seq);
return target;
}
/* Otherwise discard the sequence and fall back to code with /* If we could do the conditional move, emit the sequence,
branches. */ and return. */
end_sequence (); if (insn)
} {
rtx seq = get_insns ();
end_sequence ();
emit_insn (seq);
return target;
}
/* Otherwise discard the sequence and fall back to code with
branches. */
end_sequence ();
}
#endif #endif
if (target != op0) if (target != op0)
emit_move_insn (target, op0); emit_move_insn (target, op0);
temp = gen_label_rtx (); temp = gen_label_rtx ();
/* If this mode is an integer too wide to compare properly, /* If this mode is an integer too wide to compare properly,
compare word by word. Rely on cse to optimize constant cases. */ compare word by word. Rely on cse to optimize constant cases. */
if (GET_MODE_CLASS (mode) == MODE_INT if (GET_MODE_CLASS (mode) == MODE_INT
&& ! can_compare_p (GE, mode, ccp_jump)) && ! can_compare_p (GE, mode, ccp_jump))
{ {
if (code == MAX_EXPR) if (code == MAX_EXPR)
do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1, do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
NULL_RTX, temp); NULL_RTX, temp);
else else
do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target, do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
NULL_RTX, temp); NULL_RTX, temp);
} }
else else
{ {
do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE, do_compare_rtx_and_jump (target, cmpop1, comparison_code,
unsignedp, mode, NULL_RTX, NULL_RTX, temp); unsignedp, mode, NULL_RTX, NULL_RTX, temp);
} }
}
emit_move_insn (target, op1); emit_move_insn (target, op1);
emit_label (temp); emit_label (temp);
return target; return target;
......
2005-11-12 Jan Hubicka <jh@suse.cz>
* gcc.target/i386/minmax-1.c: New.
* gcc.target/i386/minmax-2.c: New.
2005-11-12 Kaz Kojima <kkojima@gcc.gnu.org> 2005-11-12 Kaz Kojima <kkojima@gcc.gnu.org>
* gcc.dg/pr24445.c: Fix for 64-bit targets. * gcc.dg/pr24445.c: Fix for 64-bit targets.
/* { dg-do compile } */
/* { dg-options "-O2 -march=opteron" } */
/* { dg-final { scan-assembler "test" } } */
/* { dg-final { scan-assembler-not "cmp" } } */
#define max(a,b) (((a) > (b))? (a) : (b))
t(int a)
{
return (max(a,1));
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "test" } } */
/* { dg-final { scan-assembler-not "cmp" } } */
#define max(a,b) (((a) > (b))? (a) : (b))
t(unsigned int a)
{
return (max(a,1));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment