Hi all,

This is a backport patch to fix PR63424. The previous change in trunk is here: https://gcc.gnu.org/ml/gcc-patches/2014-10/msg03306.html and commit log is here: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=217786

aarch64-none-elf toolchain has been tested on the model, no regressions.

Is it Okay for branch 4.9?

gcc/ChangeLog:

2014-11-19 Renlin Li <renlin...@arm.com>
    PR target/63424
    * config/aarch64/aarch64-simd.md (<su><maxmin>v2di3): New.

gcc/testsuite/ChangeLog:

2014-11-19 Renlin Li <renlin...@arm.com>
    PR target/63424
    * gcc.target/aarch64/pr63424.c: New Test.

diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index cab26a3..41ddbb4 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -951,6 +951,41 @@
   [(set_attr "type" "neon_minmax<q>")]
 )
 
+(define_expand "<su><maxmin>v2di3"
+  [(parallel [
+    (set (match_operand:V2DI 0 "register_operand" "")
+	 (MAXMIN:V2DI (match_operand:V2DI 1 "register_operand" "")
+		  (match_operand:V2DI 2 "register_operand" "")))
+    (clobber (reg:CC CC_REGNUM))])]
+  "TARGET_SIMD"
+{
+  enum rtx_code cmp_operator;
+  rtx cmp_fmt;
+
+  switch (<CODE>)
+    {
+    case UMIN:
+      cmp_operator = LTU;
+      break;
+    case SMIN:
+      cmp_operator = LT;
+      break;
+    case UMAX:
+      cmp_operator = GTU;
+      break;
+    case SMAX:
+      cmp_operator = GT;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  cmp_fmt = gen_rtx_fmt_ee (cmp_operator, V2DImode, operands[1], operands[2]);
+  emit_insn (gen_aarch64_vcond_internalv2div2di (operands[0], operands[1],
+              operands[2], cmp_fmt, operands[1], operands[2]));
+  DONE;
+})
+
 ;; vec_concat gives a new vector with the low elements from operand 1, and
 ;; the high elements from operand 2.  That is to say, given op1 = { a, b }
 ;; op2 = { c, d }, vec_concat (op1, op2) = { a, b, c, d }.
diff --git a/gcc/testsuite/gcc.target/aarch64/pr63424.c b/gcc/testsuite/gcc.target/aarch64/pr63424.c
new file mode 100644
index 0000000..c6bd762
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr63424.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdint.h>
+
+uint32_t
+truncate_int (const unsigned long long value)
+{
+  if ( value < 0 )
+    {
+      return 0;
+    }
+  else if ( value > UINT32_MAX )
+    {
+      return UINT32_MAX;
+    }
+  else
+    return (uint32_t)value;
+}
+
+uint32_t
+mul (const unsigned long long x, const unsigned long long y)
+{
+  uint32_t value = truncate_int (x * y);
+  return value;
+}
+
+uint32_t *
+test(unsigned size, uint32_t *a, uint32_t s)
+{
+  unsigned i;
+
+  for (i = 0; i < size; i++)
+    {
+      a[i] = mul (a[i], s);
+    }
+
+  return a;
+}

Reply via email to