]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[ARM] PR target/67929 Tighten vfp3_const_double_for_bits checks
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 27 Oct 2015 13:52:27 +0000 (13:52 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 27 Oct 2015 13:52:27 +0000 (13:52 +0000)
PR target/67929
* config/arm/arm.c (vfp3_const_double_for_bits): Rewrite.
* config/arm/constraints.md (Dp): Update callsite.
* config/arm/predicates.md (const_double_vcvt_power_of_two): Likewise.

* gcc.target/arm/pr67929_1.c: New test.

From-SVN: r229441

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/constraints.md
gcc/config/arm/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr67929_1.c [new file with mode: 0644]

index b1d6892dfbe73ef0ba8cbf2a5ec100bce5c54eb3..d64ff91a994b9ddd37fc4bc83ef1d9230a0d59ee 100644 (file)
@@ -1,3 +1,10 @@
+2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/67929
+       * config/arm/arm.c (vfp3_const_double_for_bits): Rewrite.
+       * config/arm/constraints.md (Dp): Update callsite.
+       * config/arm/predicates.md (const_double_vcvt_power_of_two): Likewise.
+
 2015-10-25  John David Anglin  <danglin@gcc.gnu.org>
 
        PR middle-end/68079
index 1cbff96bd51a94e24cadc7559b3b7c8e7d13b306..8ba60608a8fc0a05d70e787c9e0914e4f8dcbb8f 100644 (file)
@@ -29833,25 +29833,36 @@ vfp3_const_double_for_fract_bits (rtx operand)
   return 0;
 }
 
+/* If X is a CONST_DOUBLE with a value that is a power of 2 whose
+   log2 is in [1, 32], return that log2.  Otherwise return -1.
+   This is used in the patterns for vcvt.s32.f32 floating-point to
+   fixed-point conversions.  */
+
 int
-vfp3_const_double_for_bits (rtx operand)
+vfp3_const_double_for_bits (rtx x)
 {
-  REAL_VALUE_TYPE r0;
+  if (!CONST_DOUBLE_P (x))
+    return -1;
 
-  if (!CONST_DOUBLE_P (operand))
-    return 0;
+  REAL_VALUE_TYPE r;
 
-  REAL_VALUE_FROM_CONST_DOUBLE (r0, operand);
-  if (exact_real_truncate (DFmode, &r0))
-    {
-      HOST_WIDE_INT value = real_to_integer (&r0);
-      value = value & 0xffffffff;
-      if ((value != 0) && ( (value & (value - 1)) == 0))
-       return int_log2 (value);
-    }
+  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+  if (REAL_VALUE_NEGATIVE (r)
+      || REAL_VALUE_ISNAN (r)
+      || REAL_VALUE_ISINF (r)
+      || !real_isinteger (&r, SFmode))
+    return -1;
 
-  return 0;
+  HOST_WIDE_INT hwint = exact_log2 (real_to_integer (&r));
+
+  /* The exact_log2 above will have returned -1 if this is
+     not an exact log2.  */
+  if (!IN_RANGE (hwint, 1, 32))
+    return -1;
+
+  return hwint;
 }
+
 \f
 /* Emit a memory barrier around an atomic sequence according to MODEL.  */
 
index f848664d57db00c3cda380690efdec4b6d03cfac..62da4fd3987131d09fb8b4f0dffe6b9422685bd6 100644 (file)
  "@internal
   In ARM/ Thumb2 a const_double which can be used with a vcvt.s32.f32 with bits operation"
   (and (match_code "const_double")
-       (match_test "TARGET_32BIT && TARGET_VFP && vfp3_const_double_for_bits (op)")))
+       (match_test "TARGET_32BIT && TARGET_VFP
+                   && vfp3_const_double_for_bits (op) > 0")))
 
 (define_register_constraint "Ts" "(arm_restrict_it) ? LO_REGS : GENERAL_REGS"
  "For arm_restrict_it the core registers @code{r0}-@code{r7}.  GENERAL_REGS otherwise.")
index 6273e8820c6b71c1b5846125b2e265f89a66ce2d..ab9c26a751df9ad0d09a3f3960d49a8c00b1b438 100644 (file)
 (define_predicate "const_double_vcvt_power_of_two"
   (and (match_code "const_double")
        (match_test "TARGET_32BIT && TARGET_VFP
-                   && vfp3_const_double_for_bits (op)")))
+                   && vfp3_const_double_for_bits (op) > 0")))
 
 (define_predicate "neon_struct_operand"
   (and (match_code "mem")
index 3c81539b880bd9788ed86b1ed0b4ec5e61846861..87d2c39b0d7e3a21e87a7f706433983bdf1beeaa 100644 (file)
@@ -3,6 +3,11 @@
        PR fortran/58754
        * gfortran.dg/pr58754.f90: New test
 
+2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/67929
+       * gcc.target/arm/pr67929_1.c: New test.
+
 2013-10-19  Paul Thomas  <pault@gcc.gnu.org>
 
        Backport from trunk
diff --git a/gcc/testsuite/gcc.target/arm/pr67929_1.c b/gcc/testsuite/gcc.target/arm/pr67929_1.c
new file mode 100644 (file)
index 0000000..14943b6
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_vfp3_ok } */
+/* { dg-options "-O2 -fno-inline" } */
+/* { dg-add-options arm_vfp3 } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+
+int
+foo (float a)
+{
+  return a * 4.9f;
+}
+
+
+int
+main (void)
+{
+  if (foo (10.0f) != 49)
+    __builtin_abort ();
+
+  return 0;
+}
\ No newline at end of file