aboutsummaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-01-07 22:09:21 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2003-01-07 21:09:21 +0000
commit068f5deabfc16d0a4ae112d185c85d9f6bc76eed (patch)
tree0f2ce69928d0a8166860b927857a84fead2f2d9f /gcc/ifcvt.c
parenteb70d86d7eed92f410073ac5312c89840b209d7c (diff)
downloadgcc-068f5deabfc16d0a4ae112d185c85d9f6bc76eed.zip
gcc-068f5deabfc16d0a4ae112d185c85d9f6bc76eed.tar.gz
gcc-068f5deabfc16d0a4ae112d185c85d9f6bc76eed.tar.bz2
re PR target/8322 (SSE2 intrinsics broken?)
* genopinit.c (optabs): Add addc_optab. * ifcvt.c (noce_try_store_flag): Rename to ... (noce_try_addcc): ... this one; handle generic conditional increment. (noce_process_if_block): Update noce_try_addcc call. * optabs.c (emit_conditional_add): New. (init_obtabs): Initialize addc_optab. * optabs.h (optab_index): Add OTI_addcc. (addcc_optab): New macro. * md.texi: Document addMcc PR target/8322 * i386.c (ix86_init_mmx_sse_builtins): Constify arguments of loads. * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts. * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts. * reload1.c (delete_output_reload): Avoid repeated attempts to delete insn. From-SVN: r61019
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 0652afd..3cf0194 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -582,7 +582,7 @@ struct noce_if_info
static rtx noce_emit_store_flag PARAMS ((struct noce_if_info *,
rtx, int, int));
static int noce_try_store_flag PARAMS ((struct noce_if_info *));
-static int noce_try_store_flag_inc PARAMS ((struct noce_if_info *));
+static int noce_try_addcc PARAMS ((struct noce_if_info *));
static int noce_try_store_flag_constants PARAMS ((struct noce_if_info *));
static int noce_try_store_flag_mask PARAMS ((struct noce_if_info *));
static rtx noce_emit_cmove PARAMS ((struct noce_if_info *,
@@ -864,43 +864,32 @@ noce_try_store_flag_constants (if_info)
similarly for "foo--". */
static int
-noce_try_store_flag_inc (if_info)
+noce_try_addcc (if_info)
struct noce_if_info *if_info;
{
rtx target, seq;
int subtract, normalize;
if (! no_new_pseudos
- && (BRANCH_COST >= 2
- || HAVE_incscc
- || HAVE_decscc)
/* Should be no `else' case to worry about. */
&& if_info->b == if_info->x
&& GET_CODE (if_info->a) == PLUS
- && (XEXP (if_info->a, 1) == const1_rtx
- || XEXP (if_info->a, 1) == constm1_rtx)
&& rtx_equal_p (XEXP (if_info->a, 0), if_info->x)
&& (reversed_comparison_code (if_info->cond, if_info->jump)
!= UNKNOWN))
{
- if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
- subtract = 0, normalize = 0;
- else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
- subtract = 1, normalize = 0;
- else
- subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
-
- start_sequence ();
+ rtx cond = if_info->cond;
+ enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
- target = noce_emit_store_flag (if_info,
- gen_reg_rtx (GET_MODE (if_info->x)),
- 1, normalize);
-
- if (target)
- target = expand_simple_binop (GET_MODE (if_info->x),
- subtract ? MINUS : PLUS,
- if_info->x, target, if_info->x,
- 0, OPTAB_WIDEN);
+ /* First try to use addcc pattern. */
+ start_sequence ();
+ target = emit_conditional_add (if_info->x, code,
+ XEXP (cond, 0), XEXP (cond, 1),
+ VOIDmode,
+ if_info->b, XEXP (if_info->a, 1),
+ GET_MODE (if_info->x),
+ (code == LTU || code == GEU
+ || code == LEU || code == GTU));
if (target)
{
if (target != if_info->x)
@@ -908,17 +897,54 @@ noce_try_store_flag_inc (if_info)
seq = get_insns ();
end_sequence ();
-
- if (seq_contains_jump (seq))
- return FALSE;
-
emit_insn_before_scope (seq, if_info->jump,
INSN_SCOPE (if_info->insn_a));
-
return TRUE;
}
-
end_sequence ();
+
+ /* If that fails, construct conditional increment or decrement using
+ setcc. */
+ if (BRANCH_COST >= 2
+ && (XEXP (if_info->a, 1) == const1_rtx
+ || XEXP (if_info->a, 1) == constm1_rtx))
+ {
+ start_sequence ();
+ if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
+ subtract = 0, normalize = 0;
+ else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
+ subtract = 1, normalize = 0;
+ else
+ subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
+
+
+ target = noce_emit_store_flag (if_info,
+ gen_reg_rtx (GET_MODE (if_info->x)),
+ 1, normalize);
+
+ if (target)
+ target = expand_simple_binop (GET_MODE (if_info->x),
+ subtract ? MINUS : PLUS,
+ if_info->x, target, if_info->x,
+ 0, OPTAB_WIDEN);
+ if (target)
+ {
+ if (target != if_info->x)
+ noce_emit_move_insn (if_info->x, target);
+
+ seq = get_insns ();
+ end_sequence ();
+
+ if (seq_contains_jump (seq))
+ return FALSE;
+
+ emit_insn_before_scope (seq, if_info->jump,
+ INSN_SCOPE (if_info->insn_a));
+
+ return TRUE;
+ }
+ end_sequence ();
+ }
}
return FALSE;
@@ -1860,7 +1886,7 @@ noce_process_if_block (ce_info)
{
if (noce_try_store_flag_constants (&if_info))
goto success;
- if (noce_try_store_flag_inc (&if_info))
+ if (noce_try_addcc (&if_info))
goto success;
if (noce_try_store_flag_mask (&if_info))
goto success;