optabs.c (expand_parity): Fix mode mismatch, add final conversion and keep looping...
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 15 Oct 2016 18:46:02 +0000 (18:46 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 15 Oct 2016 18:46:02 +0000 (18:46 +0000)
* optabs.c (expand_parity): Fix mode mismatch, add final conversion
and keep looping on failure.

From-SVN: r241202

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sparc/popc-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sparc/popc-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sparc/popc.c [deleted file]

index 2cf3f940d8824e761f88c0169b36105971aaf871..a5744845f15f4cd77e7e9ca250ab5c2138f9115a 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-15  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * optabs.c (expand_parity): Fix mode mismatch, add final conversion
+       and keep looping on failure.
+
 2016-10-14  David Malcolm  <dmalcolm@redhat.com>
 
        * print-rtl-function.c (print_edge): Omit "(flags)" when none are
index c5e9b4f8e135add93b34f13e6f5b2b020682173e..f78d9989f050ce90273dab6a68f16a6421157636 100644 (file)
@@ -2382,18 +2382,26 @@ expand_parity (machine_mode mode, rtx op0, rtx target)
 
              last = get_last_insn ();
 
-             if (target == 0)
-               target = gen_reg_rtx (mode);
+             if (target == 0 || GET_MODE (target) != wider_mode)
+               target = gen_reg_rtx (wider_mode);
+
              xop0 = widen_operand (op0, wider_mode, mode, true, false);
              temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
                                  true);
              if (temp != 0)
                temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
                                     target, true, OPTAB_DIRECT);
-             if (temp == 0)
-               delete_insns_since (last);
 
-             return temp;
+             if (temp)
+               {
+                 if (mclass != MODE_INT
+                     || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
+                   return convert_to_mode (mode, temp, 0);
+                 else
+                   return gen_lowpart (mode, temp);
+               }
+             else
+               delete_insns_since (last);
            }
        }
     }
index 63eafa620dc1a73d7c5fdea1f5482e1a9ac1120d..d3183332a4bb1f35722969113bdc05459c2d0084 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-15  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.target/sparc/popc.c: Rename to...
+       * gcc.target/sparc/popc-1.c: ...this.
+       * gcc.target/sparc/popc-2.c: New test.
+
 2016-10-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/77972
diff --git a/gcc/testsuite/gcc.target/sparc/popc-1.c b/gcc/testsuite/gcc.target/sparc/popc-1.c
new file mode 100644 (file)
index 0000000..5442a61
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=niagara2" } */
+int test_popcount(int a)
+{
+  return __builtin_popcount(a);
+}
+
+long test_popcountl(long a)
+{
+  return __builtin_popcountl(a);
+}
+
+long long test_popcountll(long long a)
+{
+  return __builtin_popcountll(a);
+}
+
+/* { dg-final { scan-assembler-times "popc\t%" 3 } } */
diff --git a/gcc/testsuite/gcc.target/sparc/popc-2.c b/gcc/testsuite/gcc.target/sparc/popc-2.c
new file mode 100644 (file)
index 0000000..8809f18
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=niagara2 -Os" } */
+
+int foo (unsigned long long l)
+{
+  return __builtin_parityll (l);
+}
diff --git a/gcc/testsuite/gcc.target/sparc/popc.c b/gcc/testsuite/gcc.target/sparc/popc.c
deleted file mode 100644 (file)
index 5442a61..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mcpu=niagara2" } */
-int test_popcount(int a)
-{
-  return __builtin_popcount(a);
-}
-
-long test_popcountl(long a)
-{
-  return __builtin_popcountl(a);
-}
-
-long long test_popcountll(long long a)
-{
-  return __builtin_popcountll(a);
-}
-
-/* { dg-final { scan-assembler-times "popc\t%" 3 } } */