From: Ulrich Weigand Date: Wed, 19 Oct 2011 12:17:35 +0000 (+0000) Subject: re PR target/50310 (ICE: in gen_vcondv2div2df, at config/i386/sse.md:1435 with -O... X-Git-Tag: releases/gcc-4.7.0~2984 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193;p=thirdparty%2Fgcc.git re PR target/50310 (ICE: in gen_vcondv2div2df, at config/i386/sse.md:1435 with -O -ftree-vectorize and __builtin_isunordered()) PR target/50310 * config/spu/spu.c (spu_emit_vector_compare): Support unordered floating-point comparisons. From-SVN: r180184 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edaa4b7685c5..115c5d920c19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-19 Ulrich Weigand + + PR target/50310 + * config/spu/spu.c (spu_emit_vector_compare): Support unordered + floating-point comparisons. + 2011-10-19 Jan Hubicka * cgraphunit.c (handle_alias_pairs): Also handle wekref with destination diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 3baa2ebc925c..734c2beec4cc 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -6415,13 +6415,24 @@ spu_emit_vector_compare (enum rtx_code rcode, try_again = true; break; case NE: + case UNEQ: + case UNLE: + case UNLT: + case UNGE: + case UNGT: + case UNORDERED: /* Treat A != B as ~(A==B). */ { + enum rtx_code rev_code; enum insn_code nor_code; - rtx eq_rtx = spu_emit_vector_compare (EQ, op0, op1, dest_mode); + rtx rev_mask; + + rev_code = reverse_condition_maybe_unordered (rcode); + rev_mask = spu_emit_vector_compare (rev_code, op0, op1, dest_mode); + nor_code = optab_handler (one_cmpl_optab, dest_mode); gcc_assert (nor_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (nor_code) (mask, eq_rtx)); + emit_insn (GEN_FCN (nor_code) (mask, rev_mask)); if (dmode != dest_mode) { rtx temp = gen_reg_rtx (dest_mode); @@ -6466,6 +6477,48 @@ spu_emit_vector_compare (enum rtx_code rcode, return mask; } break; + case LTGT: + /* Try LT OR GT */ + { + rtx lt_rtx, gt_rtx; + enum insn_code ior_code; + + lt_rtx = spu_emit_vector_compare (LT, op0, op1, dest_mode); + gt_rtx = spu_emit_vector_compare (GT, op0, op1, dest_mode); + + ior_code = optab_handler (ior_optab, dest_mode); + gcc_assert (ior_code != CODE_FOR_nothing); + emit_insn (GEN_FCN (ior_code) (mask, lt_rtx, gt_rtx)); + if (dmode != dest_mode) + { + rtx temp = gen_reg_rtx (dest_mode); + convert_move (temp, mask, 0); + return temp; + } + return mask; + } + break; + case ORDERED: + /* Implement as (A==A) & (B==B) */ + { + rtx a_rtx, b_rtx; + enum insn_code and_code; + + a_rtx = spu_emit_vector_compare (EQ, op0, op0, dest_mode); + b_rtx = spu_emit_vector_compare (EQ, op1, op1, dest_mode); + + and_code = optab_handler (and_optab, dest_mode); + gcc_assert (and_code != CODE_FOR_nothing); + emit_insn (GEN_FCN (and_code) (mask, a_rtx, b_rtx)); + if (dmode != dest_mode) + { + rtx temp = gen_reg_rtx (dest_mode); + convert_move (temp, mask, 0); + return temp; + } + return mask; + } + break; default: gcc_unreachable (); }