From 85f5231d73ab398af64c03e4121ab16c6c172cf6 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 27 Oct 2015 12:23:51 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 7 +++++ gcc/config/arm/arm.c | 38 ++++++++++++++++-------- gcc/config/arm/constraints.md | 3 +- gcc/config/arm/predicates.md | 2 +- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/arm/pr67929_1.c | 21 +++++++++++++ 6 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr67929_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8880e994361..96af75db414 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-10-27 Kyrylo Tkachov + + 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 * builtins.c (fold_builtin_load_exponent): Rename to... diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index a379121494e..a598c84392d 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 e24858fe45e..901cfe54d24 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 08cc89924d7..48e4ba86e7b 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 5a99607884f..612e52f8929 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-27 Kyrylo Tkachov + + PR target/67929 + * gcc.target/arm/pr67929_1.c: New test. + 2015-10-27 Richard Sandiford * 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 00000000000..14943b6b598 --- /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 -- 2.30.2