aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2015-10-27 12:23:51 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2015-10-27 12:23:51 +0000
commit85f5231d73ab398af64c03e4121ab16c6c172cf6 (patch)
tree7c83b571709ea976ea9027deb40568a1997e9227 /gcc
parent86c0733fed7007dd41efe7739c8295e9933e7f98 (diff)
downloadgcc-85f5231d73ab398af64c03e4121ab16c6c172cf6.zip
gcc-85f5231d73ab398af64c03e4121ab16c6c172cf6.tar.gz
gcc-85f5231d73ab398af64c03e4121ab16c6c172cf6.tar.bz2
[ARM] PR target/67929 Tighten vfp3_const_double_for_bits checks
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: r229436
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm.c38
-rw-r--r--gcc/config/arm/constraints.md3
-rw-r--r--gcc/config/arm/predicates.md2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr67929_1.c21
6 files changed, 61 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8880e99..96af75d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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-27 Richard Sandiford <richard.sandiford@arm.com>
* builtins.c (fold_builtin_load_exponent): Rename to...
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a379121..a598c84 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -27747,25 +27747,37 @@ 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)
{
- const REAL_VALUE_TYPE *r0;
+ const REAL_VALUE_TYPE *r;
- if (!CONST_DOUBLE_P (operand))
- return 0;
+ if (!CONST_DOUBLE_P (x))
+ return -1;
- r0 = CONST_DOUBLE_REAL_VALUE (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);
- }
+ r = CONST_DOUBLE_REAL_VALUE (x);
- return 0;
+ if (REAL_VALUE_NEGATIVE (*r)
+ || REAL_VALUE_ISNAN (*r)
+ || REAL_VALUE_ISINF (*r)
+ || !real_isinteger (r, SFmode))
+ return -1;
+
+ 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;
}
+
/* Emit a memory barrier around an atomic sequence according to MODEL. */
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index e24858f..901cfe5 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -339,7 +339,8 @@
"@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.")
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 08cc899..48e4ba8 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -668,7 +668,7 @@
(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")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a99607..612e52f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/67929
+ * gcc.target/arm/pr67929_1.c: New test.
+
2015-10-27 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/torture/builtin-ldexp-1.c: Skip at -O9,
diff --git a/gcc/testsuite/gcc.target/arm/pr67929_1.c b/gcc/testsuite/gcc.target/arm/pr67929_1.c
new file mode 100644
index 0000000..14943b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr67929_1.c
@@ -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