diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2011-10-19 12:17:35 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2011-10-19 12:17:35 +0000 |
commit | 7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193 (patch) | |
tree | 92876f93036515c56b2bed131eccda5fa4b05c94 /gcc | |
parent | a66f86bbc475f720f64fd6ae3873bf8e36a8e1e7 (diff) | |
download | gcc-7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193.zip gcc-7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193.tar.gz gcc-7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/spu/spu.c | 57 |
2 files changed, 61 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edaa4b7..115c5d9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + PR target/50310 + * config/spu/spu.c (spu_emit_vector_compare): Support unordered + floating-point comparisons. + 2011-10-19 Jan Hubicka <jh@suse.cz> * 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 3baa2eb..734c2be 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 (); } |