aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2011-10-19 12:17:35 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2011-10-19 12:17:35 +0000
commit7f9a3dcd7d1981f6ef2d3ab7ab51b200715b8193 (patch)
tree92876f93036515c56b2bed131eccda5fa4b05c94 /gcc
parenta66f86bbc475f720f64fd6ae3873bf8e36a8e1e7 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/config/spu/spu.c57
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 ();
}