diff options
author | Jan Hubicka <jh@suse.cz> | 2003-01-07 22:09:21 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-01-07 21:09:21 +0000 |
commit | 068f5deabfc16d0a4ae112d185c85d9f6bc76eed (patch) | |
tree | 0f2ce69928d0a8166860b927857a84fead2f2d9f /gcc/ifcvt.c | |
parent | eb70d86d7eed92f410073ac5312c89840b209d7c (diff) | |
download | gcc-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.c | 88 |
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; |