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
This commit is contained in:
parent
df25924573
commit
230dedb327
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
* config/bfin/bfin.h (REGISTER_NAMES, SHORT_REGISTER_NAMES,
|
||||
|
|
131
gcc/expr.c
131
gcc/expr.c
|
@ -8020,69 +8020,92 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
if (! CONSTANT_P (op1))
|
||||
op1 = force_reg (mode, op1);
|
||||
|
||||
{
|
||||
enum rtx_code comparison_code;
|
||||
rtx cmpop1 = op1;
|
||||
|
||||
if (code == MAX_EXPR)
|
||||
comparison_code = unsignedp ? GEU : GE;
|
||||
else
|
||||
comparison_code = unsignedp ? LEU : LE;
|
||||
|
||||
/* Canonicalize to comparsions against 0. */
|
||||
if (op1 == const1_rtx)
|
||||
{
|
||||
/* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
|
||||
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))
|
||||
{
|
||||
enum rtx_code comparison_code;
|
||||
rtx insn;
|
||||
/* Use a conditional move if possible. */
|
||||
if (can_conditionally_move_p (mode))
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
if (code == MAX_EXPR)
|
||||
comparison_code = unsignedp ? GEU : GE;
|
||||
else
|
||||
comparison_code = unsignedp ? LEU : LE;
|
||||
/* ??? 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 ();
|
||||
|
||||
/* ??? 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 ();
|
||||
start_sequence ();
|
||||
|
||||
start_sequence ();
|
||||
/* Try to emit the conditional move. */
|
||||
insn = emit_conditional_move (target, comparison_code,
|
||||
op0, cmpop1, mode,
|
||||
op0, op1, mode,
|
||||
unsignedp);
|
||||
|
||||
/* Try to emit the conditional move. */
|
||||
insn = emit_conditional_move (target, comparison_code,
|
||||
op0, op1, mode,
|
||||
op0, op1, mode,
|
||||
unsignedp);
|
||||
/* If we could do the conditional move, emit the sequence,
|
||||
and return. */
|
||||
if (insn)
|
||||
{
|
||||
rtx seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn (seq);
|
||||
return target;
|
||||
}
|
||||
|
||||
/* If we could do the conditional move, emit the sequence,
|
||||
and return. */
|
||||
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 ();
|
||||
}
|
||||
/* Otherwise discard the sequence and fall back to code with
|
||||
branches. */
|
||||
end_sequence ();
|
||||
}
|
||||
#endif
|
||||
if (target != op0)
|
||||
emit_move_insn (target, op0);
|
||||
if (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,
|
||||
compare word by word. Rely on cse to optimize constant cases. */
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& ! can_compare_p (GE, mode, ccp_jump))
|
||||
{
|
||||
if (code == MAX_EXPR)
|
||||
do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
|
||||
NULL_RTX, temp);
|
||||
else
|
||||
do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
|
||||
NULL_RTX, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE,
|
||||
unsignedp, mode, NULL_RTX, NULL_RTX, temp);
|
||||
}
|
||||
/* If this mode is an integer too wide to compare properly,
|
||||
compare word by word. Rely on cse to optimize constant cases. */
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& ! can_compare_p (GE, mode, ccp_jump))
|
||||
{
|
||||
if (code == MAX_EXPR)
|
||||
do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
|
||||
NULL_RTX, temp);
|
||||
else
|
||||
do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
|
||||
NULL_RTX, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_compare_rtx_and_jump (target, cmpop1, comparison_code,
|
||||
unsignedp, mode, NULL_RTX, NULL_RTX, temp);
|
||||
}
|
||||
}
|
||||
emit_move_insn (target, op1);
|
||||
emit_label (temp);
|
||||
return target;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
* gcc.dg/pr24445.c: Fix for 64-bit targets.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/* { 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));
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/* { 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));
|
||||
}
|
Loading…
Reference in New Issue