Commit 5b4f088d by Martin Sebor

PR tree-optimization/78696 - [7 Regression] -fprintf-return-value misoptimizes…

PR tree-optimization/78696 - [7 Regression] -fprintf-return-value misoptimizes %.Ng where N is greater than 10

gcc/ChangeLog:

	PR tree-optimization/78696
	* gimple-ssa-sprintf.c (format_floating): Correct handling of
	precision.  Use MPFR for %f for greater fidelity.  Correct handling
	of %g.
	(pass_sprintf_length::compute_format_length): Set width and precision
	specified by asrerisk to void_node for vararg functions.
	(try_substitute_return_value): Adjust dump output.

gcc/testsuite/ChangeLog:

	PR tree-optimization/78696
	* gcc.dg/tree-ssa/builtin-sprintf-5.c: Remove incorrect test cases.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-7.c: Correct off-by-1 errors.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-9.c: New test.
	* gcc.dg/tree-ssa/builtin-sprintf.c: Add test cases.

From-SVN: r244037
parent 0f2a6e84
2017-01-03 Martin Sebor <msebor@redhat.com>
PR tree-optimization/78696
* gimple-ssa-sprintf.c (format_floating): Correct handling of
precision. Use MPFR for %f for greater fidelity. Correct handling
of %g.
(pass_sprintf_length::compute_format_length): Set width and precision
specified by asrerisk to void_node for vararg functions.
(try_substitute_return_value): Adjust dump output.
2017-01-03 David Edelsohn <dje.gcc@gmail.com> 2017-01-03 David Edelsohn <dje.gcc@gmail.com>
* doc/invoke.texi (RS6000 options): LRA is enabled by default. * doc/invoke.texi (RS6000 options): LRA is enabled by default.
......
2017-01-03 Martin Sebor <msebor@redhat.com>
PR tree-optimization/78696
* gcc.dg/tree-ssa/builtin-sprintf-5.c: Remove incorrect test cases.
* gcc.dg/tree-ssa/builtin-sprintf-warn-7.c: Correct off-by-1 errors.
* gcc.dg/tree-ssa/builtin-sprintf-warn-9.c: New test.
* gcc.dg/tree-ssa/builtin-sprintf.c: Add test cases.
2017-01-03 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/dg-test-1.c: Add tests of relative line specifications
with more than one digit.
* lib/gcc-dg.exp (process-message): Support more than one digit
in relative line specifications.
2017-01-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/78965
* gcc.dg/pr78965.c: New test.
PR middle-end/78901
* g++.dg/opt/pr78901.C: New test.
2017-01-03 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/78534
PR fortran/66310
* gfortran.dg/dependency_49.f90: Change scan-tree-dump-times
due to gfc_trans_string_copy change to avoid -Wstringop-overflow.
* gfortran.dg/repeat_4.f90: Use integers of kind C_SIZE_T.
* gfortran.dg/repeat_7.f90: New test for PR 66310.
* gfortran.dg/scan_2.f90: Handle potential cast in assignment.
* gfortran.dg/string_1.f90: Limit to ilp32 targets.
* gfortran.dg/string_1_lp64.f90: New test.
* gfortran.dg/string_3.f90: Limit to ilp32 targets.
* gfortran.dg/string_3_lp64.f90: New test.
* gfortran.dg/transfer_intrinsic_1.f90: Change
scan-tree-dump-times due to gfc_trans_string_copy change to
avoid -Wstringop-overflow.
2017-01-02 Uros Bizjak <ubizjak@gmail.com> 2017-01-02 Uros Bizjak <ubizjak@gmail.com>
PR target/78967 PR target/78967
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
FAIL (__LINE__)(value); \ FAIL (__LINE__)(value); \
} while (0) } while (0)
/* Verify that EXPECT == snprintf(0, 0, ...). */
#define EQL(expect, ...) \ #define EQL(expect, ...) \
do { \ do { \
int n = __builtin_snprintf (0, 0, __VA_ARGS__); \ int n = __builtin_snprintf (0, 0, __VA_ARGS__); \
...@@ -140,6 +141,7 @@ void test_arg_multiarg (int i, double d) ...@@ -140,6 +141,7 @@ void test_arg_multiarg (int i, double d)
EQL (16, "%*i %s", 12, i, "abc"); EQL (16, "%*i %s", 12, i, "abc");
} }
/* Verify that EXPECT == vsnprintf(0, 0, ...). */
#define EQLv(expect, fmt, va) \ #define EQLv(expect, fmt, va) \
do { \ do { \
int n = __builtin_vsnprintf (0, 0, fmt, va); \ int n = __builtin_vsnprintf (0, 0, fmt, va); \
...@@ -149,9 +151,7 @@ void test_arg_multiarg (int i, double d) ...@@ -149,9 +151,7 @@ void test_arg_multiarg (int i, double d)
void test_va_int (__builtin_va_list va) void test_va_int (__builtin_va_list va)
{ {
EQLv ( 2, "%02hhx", va); EQLv ( 2, "%02hhx", va);
EQLv ( 2, "%02.*hhx", va);
EQLv ( 4, "%04hx", va); EQLv ( 4, "%04hx", va);
EQLv ( 4, "%04.*hx", va);
} }
void test_va_multiarg (__builtin_va_list va) void test_va_multiarg (__builtin_va_list va)
......
...@@ -63,11 +63,14 @@ void test_floating_a_var (double x) ...@@ -63,11 +63,14 @@ void test_floating_a_var (double x)
T (0, "%.*a", INT_MIN, x); /* { dg-warning "writing between 6 and 24 bytes" } */ T (0, "%.*a", INT_MIN, x); /* { dg-warning "writing between 6 and 24 bytes" } */
T (0, "%.*a", INT_MAX, x); /* { dg-warning "writing between 2147483653 and 2147483658 bytes" } */ /* Expected output is "0x0." followed by INT_MAX digits followed by
"p+" followed by 1 to four digits, with a byte count in the range
[3 + INT_MAX + 2 + 1, 3 + INT_MAX + 2 + 4]. */
T (0, "%.*a", INT_MAX, x); /* { dg-warning "writing between 2147483654 and 2147483658 bytes" } */
T (0, "%*.*a", INT_MIN, INT_MIN, x); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*.*a", INT_MIN, INT_MIN, x); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*.*a", INT_MAX, INT_MAX, x); /* { dg-warning "writing between 2147483653 and 2147483658 bytes" } */ T (0, "%*.*a", INT_MAX, INT_MAX, x); /* { dg-warning "writing between 2147483654 and 2147483658 bytes" } */
} }
void test_floating_e_cst (void) void test_floating_e_cst (void)
...@@ -75,7 +78,7 @@ void test_floating_e_cst (void) ...@@ -75,7 +78,7 @@ void test_floating_e_cst (void)
T (0, "%*e", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*e", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*e", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*e", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%.*e", INT_MIN, 0.); /* { dg-warning "writing 5 bytes" } */ T (0, "%.*e", INT_MIN, 0.); /* { dg-warning "writing 12 bytes" } */
T (0, "%.*e", INT_MAX, 0.); /* { dg-warning "writing 2147483653 bytes" } */ T (0, "%.*e", INT_MAX, 0.); /* { dg-warning "writing 2147483653 bytes" } */
...@@ -103,7 +106,7 @@ void test_floating_f_cst (void) ...@@ -103,7 +106,7 @@ void test_floating_f_cst (void)
T (0, "%*f", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*f", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*f", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*f", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%.*f", INT_MIN, 0.); /* { dg-warning "writing 1 byte" } */ T (0, "%.*f", INT_MIN, 0.); /* { dg-warning "writing 8 byte" } */
T (0, "%.*f", INT_MAX, 0.); /* { dg-warning "writing 2147483649 bytes" } */ T (0, "%.*f", INT_MAX, 0.); /* { dg-warning "writing 2147483649 bytes" } */
......
...@@ -56,9 +56,12 @@ checkv (const char *func, int line, int res, int min, int max, ...@@ -56,9 +56,12 @@ checkv (const char *func, int line, int res, int min, int max,
fail = 1; fail = 1;
} }
else else if (min == max)
__builtin_printf ("PASS: %s:%i: \"%s\" result %i: \"%s\"\n", __builtin_printf ("PASS: %s:%i: \"%s\" result %i: \"%s\"\n",
func, line, fmt, n, dst); func, line, fmt, n, dst);
else
__builtin_printf ("PASS: %s:%i: \"%s\" result %i in [%i, %i]: \"%s\"\n",
func, line, fmt, n, min, max, dst);
} }
if (fail) if (fail)
...@@ -75,7 +78,7 @@ check (const char *func, int line, int res, int min, int max, ...@@ -75,7 +78,7 @@ check (const char *func, int line, int res, int min, int max,
__builtin_va_end (va); __builtin_va_end (va);
} }
char buffer[256]; char buffer[4100];
char* volatile dst = buffer; char* volatile dst = buffer;
char* ptr = buffer; char* ptr = buffer;
...@@ -415,6 +418,8 @@ test_a_double (double d) ...@@ -415,6 +418,8 @@ test_a_double (double d)
EQL ( 9, 10, "%.2a", 4.0); /* 0x8.00p-1 */ EQL ( 9, 10, "%.2a", 4.0); /* 0x8.00p-1 */
EQL (10, 11, "%.3a", 5.0); /* 0xa.000p-1 */ EQL (10, 11, "%.3a", 5.0); /* 0xa.000p-1 */
EQL (11, 12, "%.*a", 4, 6.0); /* 0xc.0000p-1 */
EQL (12, 13, "%.*a", 5, 7.0); /* 0xe.00000p-1 */
/* d is in [ 0, -DBL_MAX ] */ /* d is in [ 0, -DBL_MAX ] */
RNG ( 6, 10, 11, "%.0a", d); /* 0x0p+0 ... -0x2p+1023 */ RNG ( 6, 10, 11, "%.0a", d); /* 0x0p+0 ... -0x2p+1023 */
RNG ( 6, 12, 13, "%.1a", d); /* 0x0p+0 ... -0x2.0p+1023 */ RNG ( 6, 12, 13, "%.1a", d); /* 0x0p+0 ... -0x2.0p+1023 */
...@@ -432,7 +437,7 @@ test_a_long_double (void) ...@@ -432,7 +437,7 @@ test_a_long_double (void)
} }
static void __attribute__ ((noinline, noclone)) static void __attribute__ ((noinline, noclone))
test_e_double (void) test_e_double (double d)
{ {
EQL (12, 13, "%e", 1.0e0); EQL (12, 13, "%e", 1.0e0);
EQL (13, 14, "%e", -1.0e0); EQL (13, 14, "%e", -1.0e0);
...@@ -454,10 +459,34 @@ test_e_double (void) ...@@ -454,10 +459,34 @@ test_e_double (void)
EQL (12, 13, "%e", 1.0e-1); EQL (12, 13, "%e", 1.0e-1);
EQL (12, 13, "%e", 1.0e-12); EQL (12, 13, "%e", 1.0e-12);
EQL (13, 14, "%e", 1.0e-123); EQL (13, 14, "%e", 1.0e-123);
RNG (12, 14, 15, "%e", d);
RNG ( 5, 7, 8, "%.e", d);
RNG ( 5, 7, 8, "%.0e", d);
RNG ( 7, 9, 10, "%.1e", d);
RNG ( 8, 10, 11, "%.2e", d);
RNG ( 9, 11, 12, "%.3e", d);
RNG (10, 12, 13, "%.4e", d);
RNG (11, 13, 14, "%.5e", d);
RNG (12, 14, 15, "%.6e", d);
RNG (13, 15, 16, "%.7e", d);
RNG (4006, 4008, 4009, "%.4000e", d);
RNG ( 5, 7, 8, "%.*e", 0, d);
RNG ( 7, 9, 10, "%.*e", 1, d);
RNG ( 8, 10, 11, "%.*e", 2, d);
RNG ( 9, 11, 12, "%.*e", 3, d);
RNG (10, 12, 13, "%.*e", 4, d);
RNG (11, 13, 14, "%.*e", 5, d);
RNG (12, 14, 15, "%.*e", 6, d);
RNG (13, 15, 16, "%.*e", 7, d);
RNG (4006, 4008, 4009, "%.*e", 4000, d);
} }
static void __attribute__ ((noinline, noclone)) static void __attribute__ ((noinline, noclone))
test_e_long_double (void) test_e_long_double (long double d)
{ {
EQL (12, 13, "%Le", 1.0e0L); EQL (12, 13, "%Le", 1.0e0L);
EQL (13, 14, "%Le", -1.0e0L); EQL (13, 14, "%Le", -1.0e0L);
...@@ -490,10 +519,32 @@ test_e_long_double (void) ...@@ -490,10 +519,32 @@ test_e_long_double (void)
EQL ( 8, 9, "%.1Le", 1.0e-111L); EQL ( 8, 9, "%.1Le", 1.0e-111L);
EQL (19, 20, "%.12Le", 1.0e-112L); EQL (19, 20, "%.12Le", 1.0e-112L);
EQL (20, 21, "%.13Le", 1.0e-113L); EQL (20, 21, "%.13Le", 1.0e-113L);
/* The following correspond to the double results plus 1 for the upper
bound accounting for the four-digit exponent. */
RNG (12, 15, 16, "%Le", d); /* 0.000000e+00 ... -1.189732e+4932 */
RNG ( 5, 8, 9, "%.Le", d);
RNG ( 5, 9, 10, "%.0Le", d);
RNG ( 7, 10, 11, "%.1Le", d); /* 0.0e+00 ... -1.2e+4932 */
RNG ( 8, 11, 12, "%.2Le", d); /* 0.00e+00 ... -1.19e+4932 */
RNG ( 9, 12, 13, "%.3Le", d);
RNG (10, 13, 14, "%.4Le", d);
RNG (11, 14, 15, "%.5Le", d);
RNG (12, 15, 16, "%.6Le", d); /* same as plain "%Le" */
RNG (13, 16, 17, "%.7Le", d); /* 0.0000000e+00 ... -1.1897315e+4932 */
RNG ( 5, 9, 10, "%.*Le", 0, d);
RNG ( 7, 10, 11, "%.*Le", 1, d);
RNG ( 8, 11, 12, "%.*Le", 2, d);
RNG ( 9, 12, 13, "%.*Le", 3, d);
RNG (10, 13, 14, "%.*Le", 4, d);
RNG (11, 14, 15, "%.*Le", 5, d);
RNG (12, 15, 16, "%.*Le", 6, d);
RNG (13, 16, 17, "%.*Le", 7, d);
} }
static void __attribute__ ((noinline, noclone)) static void __attribute__ ((noinline, noclone))
test_f_double (void) test_f_double (double d)
{ {
EQL ( 8, 9, "%f", 0.0e0); EQL ( 8, 9, "%f", 0.0e0);
EQL ( 8, 9, "%f", 0.1e0); EQL ( 8, 9, "%f", 0.1e0);
...@@ -511,6 +562,8 @@ test_f_double (void) ...@@ -511,6 +562,8 @@ test_f_double (void)
EQL ( 8, 9, "%f", 1.0e-1); EQL ( 8, 9, "%f", 1.0e-1);
EQL ( 8, 9, "%f", 1.0e-12); EQL ( 8, 9, "%f", 1.0e-12);
EQL ( 8, 9, "%f", 1.0e-123); EQL ( 8, 9, "%f", 1.0e-123);
RNG ( 8, 317, 318, "%f", d);
} }
static void __attribute__ ((noinline, noclone)) static void __attribute__ ((noinline, noclone))
...@@ -535,6 +588,87 @@ test_f_long_double (void) ...@@ -535,6 +588,87 @@ test_f_long_double (void)
} }
static void __attribute__ ((noinline, noclone)) static void __attribute__ ((noinline, noclone))
test_g_double (double d)
{
/* Numbers exactly representable in binary floating point. */
EQL ( 1, 2, "%g", 0.0);
EQL ( 3, 4, "%g", 1.0 / 2);
EQL ( 4, 5, "%g", 1.0 / 4);
EQL ( 5, 6, "%g", 1.0 / 8);
EQL ( 6, 7, "%g", 1.0 / 16);
EQL ( 7, 8, "%g", 1.0 / 32);
EQL ( 8, 9, "%g", 1.0 / 64);
EQL ( 9, 10, "%g", 1.0 / 128);
EQL ( 10, 11, "%g", 1.0 / 256);
EQL ( 10, 11, "%g", 1.0 / 512);
/* Numbers that are not exactly representable. */
RNG ( 3, 8, 9, "%g", 0.1);
RNG ( 4, 8, 9, "%g", 0.12);
RNG ( 5, 8, 9, "%g", 0.123);
RNG ( 6, 8, 9, "%g", 0.1234);
RNG ( 7, 8, 9, "%g", 0.12345);
RNG ( 8, 8, 9, "%g", 0.123456);
RNG ( 4, 7, 8, "%g", 0.123e+1);
EQL ( 8, 9, "%g", 0.123e+12);
RNG ( 9, 12, 13, "%g", 0.123e+134);
RNG ( 1, 13, 14, "%g", d);
RNG ( 1, 7, 8, "%.g", d);
RNG ( 1, 7, 8, "%.0g", d);
RNG ( 1, 7, 8, "%.1g", d);
RNG ( 1, 9, 10, "%.2g", d);
RNG ( 1, 10, 11, "%.3g", d);
RNG ( 1, 11, 12, "%.4g", d);
RNG ( 1, 12, 13, "%.5g", d);
RNG ( 1, 13, 14, "%.6g", d);
RNG ( 1, 14, 15, "%.7g", d);
RNG ( 1, 15, 16, "%.8g", d);
RNG ( 1,310,311, "%.9999g", d);
RNG ( 1, 7, 8, "%.*g", 0, d);
RNG ( 1, 7, 8, "%.*g", 1, d);
RNG ( 1, 9, 10, "%.*g", 2, d);
RNG ( 1, 10, 11, "%.*g", 3, d);
RNG ( 1, 11, 12, "%.*g", 4, d);
RNG ( 1, 12, 13, "%.*g", 5, d);
RNG ( 1, 13, 14, "%.*g", 6, d);
RNG ( 1, 14, 15, "%.*g", 7, d);
RNG ( 1, 15, 16, "%.*g", 8, d);
RNG ( 1,310,311, "%.*g", 9999, d);
}
static void __attribute__ ((noinline, noclone))
test_g_long_double (void)
{
/* Numbers exactly representable in binary floating point. */
EQL ( 1, 2, "%Lg", 0.0L);
EQL ( 3, 4, "%Lg", 1.0L / 2);
EQL ( 4, 5, "%Lg", 1.0L / 4);
EQL ( 5, 6, "%Lg", 1.0L / 8);
EQL ( 6, 7, "%Lg", 1.0L / 16);
EQL ( 7, 8, "%Lg", 1.0L / 32);
EQL ( 8, 9, "%Lg", 1.0L / 64);
EQL ( 9, 10, "%Lg", 1.0L / 128);
EQL ( 10, 11, "%Lg", 1.0L / 256);
EQL ( 10, 11, "%Lg", 1.0L / 512);
/* Numbers that are not exactly representable. */
RNG ( 3, 8, 9, "%Lg", 0.1L);
RNG ( 4, 8, 9, "%Lg", 0.12L);
RNG ( 5, 8, 9, "%Lg", 0.123L);
RNG ( 6, 8, 9, "%Lg", 0.1234L);
RNG ( 7, 8, 9, "%Lg", 0.12345L);
RNG ( 8, 8, 9, "%Lg", 0.123456L);
RNG ( 4, 7, 8, "%Lg", 0.123e+1L);
EQL ( 8, 9, "%Lg", 0.123e+12L);
RNG ( 9, 12, 13, "%Lg", 0.123e+134L);
}
static void __attribute__ ((noinline, noclone))
test_s (int i) test_s (int i)
{ {
EQL ( 0, 1, "%s", ""); EQL ( 0, 1, "%s", "");
...@@ -577,12 +711,14 @@ int main (void) ...@@ -577,12 +711,14 @@ int main (void)
test_x ('?', 0xdead, 0xdeadbeef); test_x ('?', 0xdead, 0xdeadbeef);
test_a_double (0.0); test_a_double (0.0);
test_e_double (); test_e_double (0.0);
test_f_double (); test_f_double (0.0);
test_g_double (0.0);
test_a_long_double (); test_a_long_double ();
test_e_long_double (); test_e_long_double (0.0);
test_f_long_double (); test_f_long_double ();
test_g_long_double ();
test_s (0); test_s (0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment