[ARM] PR target/66731 Fix vnmul insn with -frounding-math
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Mon, 3 Aug 2015 11:12:00 +0000 (11:12 +0000)
committerSzabolcs Nagy <nsz@gcc.gnu.org>
Mon, 3 Aug 2015 11:12:00 +0000 (11:12 +0000)
gcc:

PR target/66731
* config/arm/vfp.md (negmuldf3_vfp): Add new pattern.
(negmulsf3_vfp): Likewise.
(muldf3negdf_vfp): Disable for -frounding-math.
(mulsf3negsf_vfp): Likewise.
* config/arm/arm.c (arm_new_rtx_costs): Fix NEG cost for VNMUL,
fix MULT cost with -frounding-math.

gcc/testsuite:

PR target/66731
* gcc.target/arm/vnmul-1.c: New.
* gcc.target/arm/vnmul-2.c: New.
* gcc.target/arm/vnmul-3.c: New.
* gcc.target/arm/vnmul-4.c: New.

From-SVN: r226496

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/vfp.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/vnmul-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vnmul-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vnmul-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vnmul-4.c [new file with mode: 0644]

index dac24ddd44f8995267fa3aa9b7a0e810b32de335..abf05a64cce94a4de163fe689dfcacd39e93bd61 100644 (file)
@@ -1,3 +1,13 @@
+2015-08-03  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+       PR target/66731
+       * config/arm/vfp.md (negmuldf3_vfp): Add new pattern.
+       (negmulsf3_vfp): Likewise.
+       (muldf3negdf_vfp): Disable for -frounding-math.
+       (mulsf3negsf_vfp): Likewise.
+       * config/arm/arm.c (arm_new_rtx_costs): Fix NEG cost for VNMUL,
+       fix MULT cost with -frounding-math.
+
 2015-08-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * ifcvt.c (noce_try_store_flag_constants): Make logic of the case
index ae37fc7a241f59a05f3d75aa132981bc2ea6b0ab..1ea9e27f2d42cbad45cd36da0909452a12dd9509 100644 (file)
@@ -10181,7 +10181,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
        {
          rtx op0 = XEXP (x, 0);
 
-         if (GET_CODE (op0) == NEG)
+         if (GET_CODE (op0) == NEG && !flag_rounding_math)
            op0 = XEXP (op0, 0);
 
          if (speed_p)
@@ -10255,6 +10255,13 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
       if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
          && (mode == SFmode || !TARGET_VFP_SINGLE))
        {
+         if (GET_CODE (XEXP (x, 0)) == MULT)
+           {
+             /* VNMUL.  */
+             *cost = rtx_cost (XEXP (x, 0), mode, NEG, 0, speed_p);
+             return true;
+           }
+
          if (speed_p)
            *cost += extra_cost->fp[mode != SFmode].neg;
 
index f62ff793462408c8948e0ce42cd2efa3a155324d..081aab2b487048d1b4c6daa90bea80fb8afbbcf2 100644 (file)
   [(set (match_operand:SF                 0 "s_register_operand" "=t")
        (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
                 (match_operand:SF         2 "s_register_operand" "t")))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && !flag_rounding_math"
+  "vnmul%?.f32\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
+   (set_attr "type" "fmuls")]
+)
+
+(define_insn "*negmulsf3_vfp"
+  [(set (match_operand:SF                 0 "s_register_operand" "=t")
+       (neg:SF (mult:SF (match_operand:SF 1 "s_register_operand" "t")
+                (match_operand:SF         2 "s_register_operand" "t"))))]
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
   "vnmul%?.f32\\t%0, %1, %2"
   [(set_attr "predicable" "yes")
   [(set (match_operand:DF                 0 "s_register_operand" "=w")
        (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
                 (match_operand:DF         2 "s_register_operand" "w")))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
+  && !flag_rounding_math"
+  "vnmul%?.f64\\t%P0, %P1, %P2"
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
+   (set_attr "type" "fmuld")]
+)
+
+(define_insn "*negmuldf3_vfp"
+  [(set (match_operand:DF                 0 "s_register_operand" "=w")
+       (neg:DF (mult:DF (match_operand:DF 1 "s_register_operand" "w")
+                (match_operand:DF         2 "s_register_operand" "w"))))]
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
   "vnmul%?.f64\\t%P0, %P1, %P2"
   [(set_attr "predicable" "yes")
index be48d3939934a198294b74603fbacbfe425641ce..b9659ce44f44e2fb1c20adeebe4b923d877f73da 100644 (file)
@@ -1,3 +1,11 @@
+2015-08-03  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+       PR target/66731
+       * gcc.target/arm/vnmul-1.c: New.
+       * gcc.target/arm/vnmul-2.c: New.
+       * gcc.target/arm/vnmul-3.c: New.
+       * gcc.target/arm/vnmul-4.c: New.
+
 2015-08-03  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/64921
diff --git a/gcc/testsuite/gcc.target/arm/vnmul-1.c b/gcc/testsuite/gcc.target/arm/vnmul-1.c
new file mode 100644 (file)
index 0000000..af0bebe
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+/* { dg-options "-O2 -fno-rounding-math -mfpu=vfp -mfloat-abi=hard" } */
+
+double
+foo_d (double a, double b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f64" } } */
+  return -a * b;
+}
+
+float
+foo_s (float a, float b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f32" } } */
+  return -a * b;
+}
diff --git a/gcc/testsuite/gcc.target/arm/vnmul-2.c b/gcc/testsuite/gcc.target/arm/vnmul-2.c
new file mode 100644 (file)
index 0000000..909b2a4
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+/* { dg-options "-O2 -frounding-math -mfpu=vfp -mfloat-abi=hard" } */
+
+double
+foo_d (double a, double b)
+{
+  /* { dg-final { scan-assembler-not "vnmul\\.f64" } } */
+  return -a * b;
+}
+
+float
+foo_s (float a, float b)
+{
+  /* { dg-final { scan-assembler-not "vnmul\\.f32" } } */
+  return -a * b;
+}
diff --git a/gcc/testsuite/gcc.target/arm/vnmul-3.c b/gcc/testsuite/gcc.target/arm/vnmul-3.c
new file mode 100644 (file)
index 0000000..df02882
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+/* { dg-options "-O2 -fno-rounding-math -mfpu=vfp -mfloat-abi=hard" } */
+
+double
+foo_d (double a, double b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f64" } } */
+  return -(a * b);
+}
+
+float
+foo_s (float a, float b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f32" } } */
+  return -(a * b);
+}
diff --git a/gcc/testsuite/gcc.target/arm/vnmul-4.c b/gcc/testsuite/gcc.target/arm/vnmul-4.c
new file mode 100644 (file)
index 0000000..670ee40
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+/* { dg-options "-O2 -frounding-math -mfpu=vfp -mfloat-abi=hard" } */
+
+double
+foo_d (double a, double b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f64" } } */
+  return -(a * b);
+}
+
+float
+foo_s (float a, float b)
+{
+  /* { dg-final { scan-assembler "vnmul\\.f32" } } */
+  return -(a * b);
+}