On 06/18/13 09:50, Zhenqiang Chen wrote:
Hi,

During expand, function vcond<mode><mode> inverses some CMP, e.g.

    a LE b -> b GE a

But if "b" is "CONST0_RTX", "b GE a" will be an illegal insn.

(insn 933 932 934 113 (set (reg:V4SI 1027)
         (unspec:V4SI [
                 (const_vector:V4SI [
                         (const_int 0 [0])
                         (const_int 0 [0])
                         (const_int 0 [0])
                         (const_int 0 [0])
                     ])
                 (reg:V4SI 1023 [ vect_var_.49 ])
                 (const_int 1 [0x1])
             ] UNSPEC_VCGE)) PUGHSlab/Mapping.c:567 -1
      (nil))

Refer https://bugs.launchpad.net/linaro-toolchain-binaries/+bug/1189445
for more. And the bug also happens for FSF trunk.

The similar issue
(https://bugs.launchpad.net/linaro-toolchain-binaries/+bug/1163942)
had fixed on AARCH64:
http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00581.html

The patch is similar to the fix for aarch64.

Bootstrap and no make check regression on Panda Board.

Is it OK for trunk and 4.8?

No, not without an appropriate set of testcases that exercise these cases.


regards
Ramana


Thanks!
-Zhenqiang

ChangeLog:

2013-06-18  Zhenqiang Chen  <zhenqiang.c...@linaro.org>

        * config/arm/neon.md (vcond): Fix floating-point vector
        comparisons against 0.

diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index e814df0..9299ae5 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -1671,6 +1671,7 @@
                             ? 3 : 1;
    rtx magic_rtx = GEN_INT (magic_word);
    int inverse = 0;
+  int use_zero_form = 0;
    int swap_bsl_operands = 0;
    rtx mask = gen_reg_rtx (<V_cmp_result>mode);
    rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
@@ -1681,12 +1682,16 @@
    switch (GET_CODE (operands[3]))
      {
      case GE:
+    case GT:
      case LE:
+    case LT:
      case EQ:
-      if (!REG_P (operands[5])
-         && (operands[5] != CONST0_RTX (<MODE>mode)))
-       operands[5] = force_reg (<MODE>mode, operands[5]);
-      break;
+      if (operands[5] == CONST0_RTX (<MODE>mode))
+       {
+         use_zero_form = 1;
+         break;
+       }
+      /* Fall through.  */
      default:
        if (!REG_P (operands[5]))
        operands[5] = force_reg (<MODE>mode, operands[5]);
@@ -1737,7 +1742,26 @@
         a GT b -> a GT b
         a LE b -> b GE a
         a LT b -> b GT a
-        a EQ b -> a EQ b  */
+        a EQ b -> a EQ b
+        Note that there also exist direct comparison against 0 forms,
+        so catch those as a special case.  */
+      if (use_zero_form)
+       {
+         inverse = 0;
+         switch (GET_CODE (operands[3]))
+           {
+           case LT:
+             base_comparison = gen_neon_vclt<mode>;
+             break;
+           case LE:
+             base_comparison = gen_neon_vcle<mode>;
+             break;
+           default:
+             /* Do nothing, other zero form cases already have the correct
+                base_comparison.  */
+             break;
+           }
+       }

        if (!inverse)
        emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));



Reply via email to