re PR target/27842 (Miscompile of Altivec vec_abs (float) inside loop)
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 6 Jun 2006 17:01:27 +0000 (17:01 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Tue, 6 Jun 2006 17:01:27 +0000 (17:01 +0000)
PR target/27842
* config/rs6000/altivec.md (UNSPEC_VSLW): Remove.
("altivec_vspltisw_v4sf", "altivec_vslw_v4sf"): Remove.
("mulv4sf3", "absv4sf3", "negv4sf3"): Adapt users to use
V4SImode temporaries and operations instead.

PR target/27842
* gcc.dg/vmx/pr27842.c: New test.

From-SVN: r114438

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vmx/pr27842.c [new file with mode: 0644]

index 204498c60dfd8ec264d44c22ab97ebc63cab46bb..1f69780145a908ff7530aa1513edba714844d2e2 100644 (file)
@@ -1,3 +1,11 @@
+2006-06-06  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       PR target/27842
+       * config/rs6000/altivec.md (UNSPEC_VSLW): Remove.
+       ("altivec_vspltisw_v4sf", "altivec_vslw_v4sf"): Remove.
+       ("mulv4sf3", "absv4sf3", "negv4sf3"): Adapt users to use
+       V4SImode temporaries and operations instead.
+
 2006-06-06  Joseph S. Myers  <joseph@codesourcery.com>
 
        * config/mips/t-linux64 (tp-bit.c): Append to tp-bit.c, not
index d4bf08e228ce125f13ae4fc92b56e735c19f0829..e0326856f1a9bc1c90b89b971411a9c024031c56 100644 (file)
@@ -65,7 +65,6 @@
    (UNSPEC_VPKSWUS      103)
    (UNSPEC_VRL          104)
    (UNSPEC_VSL          107)
-   (UNSPEC_VSLW         109)
    (UNSPEC_VSLV4SI      110)
    (UNSPEC_VSLO         111)
    (UNSPEC_VSR          118)
   rtx neg0;
 
   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
-  neg0 = gen_reg_rtx (V4SFmode);
-  emit_insn (gen_altivec_vspltisw_v4sf (neg0, constm1_rtx));
-  emit_insn (gen_altivec_vslw_v4sf (neg0, neg0, neg0));
+  neg0 = gen_reg_rtx (V4SImode);
+  emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
+  emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
 
   /* Use the multiply-add.  */
   emit_insn (gen_altivec_vmaddfp (operands[0], operands[1], operands[2],
-                                 neg0));
+                                 gen_lowpart (V4SFmode, neg0)));
   DONE;
 }")
 
   "vsl<VI_char> %0,%1,%2"
   [(set_attr "type" "vecsimple")])
 
-(define_insn "altivec_vslw_v4sf"
-  [(set (match_operand:V4SF 0 "register_operand" "=v")
-        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
-                      (match_operand:V4SF 2 "register_operand" "v")]
-                    UNSPEC_VSLW))]
-  "TARGET_ALTIVEC"
-  "vslw %0,%1,%2"
-  [(set_attr "type" "vecsimple")])
-
 (define_insn "altivec_vsl"
   [(set (match_operand:V4SI 0 "register_operand" "=v")
         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
   "vspltis<VI_char> %0,%1"
   [(set_attr "type" "vecperm")])
 
-(define_insn "altivec_vspltisw_v4sf"
-  [(set (match_operand:V4SF 0 "register_operand" "=v")
-       (vec_duplicate:V4SF
-        (float:SF (match_operand:QI 1 "s5bit_cint_operand" "i"))))]
-  "TARGET_ALTIVEC"
-  "vspltisw %0,%1"
-  [(set_attr "type" "vecperm")])
-
 (define_insn "ftruncv4sf2"
   [(set (match_operand:V4SF 0 "register_operand" "=v")
        (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
 ;;    vandc %0,%1,SCRATCH2
 (define_expand "absv4sf2"
   [(set (match_dup 2)
-       (vec_duplicate:V4SF (float:SF (const_int -1))))
+       (vec_duplicate:V4SI (const_int -1)))
    (set (match_dup 3)
-        (unspec:V4SF [(match_dup 2) (match_dup 2)] UNSPEC_VSLW))
+        (unspec:V4SI [(match_dup 2) (match_dup 2)] UNSPEC_VSL))
    (set (match_operand:V4SF 0 "register_operand" "=v")
-        (and:V4SF (not:V4SF (match_dup 3))
+        (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
                   (match_operand:V4SF 1 "register_operand" "v")))]
   "TARGET_ALTIVEC"
 {
-  operands[2] = gen_reg_rtx (V4SFmode);
-  operands[3] = gen_reg_rtx (V4SFmode);
+  operands[2] = gen_reg_rtx (V4SImode);
+  operands[3] = gen_reg_rtx (V4SImode);
 })
 
 ;; Generate
   rtx neg0;
 
   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
-  neg0 = gen_reg_rtx (V4SFmode);
-  emit_insn (gen_altivec_vspltisw_v4sf (neg0, constm1_rtx));
-  emit_insn (gen_altivec_vslw_v4sf (neg0, neg0, neg0));
+  neg0 = gen_reg_rtx (V4SImode);
+  emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
+  emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
 
   /* XOR */
-  emit_insn (gen_xorv4sf3 (operands[0], neg0, operands[1])); 
+  emit_insn (gen_xorv4sf3 (operands[0],
+                          gen_lowpart (V4SFmode, neg0), operands[1])); 
     
   DONE;
 }")
index ace5b3f3ea90edaeead99d16d512be6598ace8a9..f4c04f117cf50a827f09f4469d56941d33157c87 100644 (file)
@@ -1,3 +1,8 @@
+2006-06-06  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       PR target/27842
+       * gcc.dg/vmx/pr27842.c: New test.
+
 2006-06-05  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
        PR libfortran/27895
diff --git a/gcc/testsuite/gcc.dg/vmx/pr27842.c b/gcc/testsuite/gcc.dg/vmx/pr27842.c
new file mode 100644 (file)
index 0000000..56b2970
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include <altivec.h>
+
+extern void abort (void);
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+
+void test (vector float *p, int n)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    p[i] = vec_abs (p[i]);
+}
+
+int
+main (void)
+{
+  vector float p = (vector float){ 0.5, 0.5, 0.5, 0.5 };
+  vector float q = p;
+
+  test (&p, 1);
+
+  if (memcmp (&p, &q, sizeof (p)))
+    abort ();
+
+  return 0;
+}
+