Hello. As described in the PR, we represent unsigned long types as gcov_type in compiler. That can lead to a negative value in context of GCOV_SINGLE_VALUE (coming from DIV/MOV expression). Thus, we have to relax the assert.
Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. And Python can be bootstrapped with the patch. Ready to be installed? Martin
>From ccee30401dc59b41f962330b5f5390075813be14 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Mon, 20 Feb 2017 15:55:08 +0100 Subject: [PATCH] Remove wrong assert about gcov_type (PR lto/79587). gcc/ChangeLog: 2017-02-20 Martin Liska <mli...@suse.cz> PR lto/79587 * data-streamer-in.c (streamer_read_gcov_count): Remove assert. * data-streamer-out.c (streamer_write_gcov_count_stream): Likewise. * value-prof.c (stream_out_histogram_value): Make assert more precise based on type of counter. gcc/testsuite/ChangeLog: 2017-02-20 Martin Liska <mli...@suse.cz> PR lto/79587 * gcc.dg/tree-prof/pr79587.c: New test. --- gcc/data-streamer-in.c | 1 - gcc/data-streamer-out.c | 1 - gcc/testsuite/gcc.dg/tree-prof/pr79587.c | 26 ++++++++++++++++++++++++++ gcc/value-prof.c | 12 +++++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-prof/pr79587.c diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c index b38d91353fc..ad32ce1e99a 100644 --- a/gcc/data-streamer-in.c +++ b/gcc/data-streamer-in.c @@ -181,7 +181,6 @@ gcov_type streamer_read_gcov_count (struct lto_input_block *ib) { gcov_type ret = streamer_read_hwi (ib); - gcc_assert (ret >= 0); return ret; } diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c index 1ee8c9f53af..1e8feb1e74a 100644 --- a/gcc/data-streamer-out.c +++ b/gcc/data-streamer-out.c @@ -340,7 +340,6 @@ streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work) void streamer_write_gcov_count_stream (struct lto_output_stream *obs, gcov_type work) { - gcc_assert (work >= 0); gcc_assert ((HOST_WIDE_INT) work == work); streamer_write_hwi_stream (obs, work); } diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr79587.c b/gcc/testsuite/gcc.dg/tree-prof/pr79587.c new file mode 100644 index 00000000000..517e0819919 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/pr79587.c @@ -0,0 +1,26 @@ +/* { dg-require-effective-target lto } */ +/* { dg-options "-O2 -flto" } */ + +unsigned long global = -12345; + +unsigned long +__attribute__((noinline)) +test(unsigned long v, unsigned long v2) +{ + unsigned long x = v % v2; + + return x; +} + +int main(int argc, char **argv) +{ + unsigned long r = 0; + + for (int i = 0; i < 100; i++) + r += test(argc, global); + + if (r != 100) + __builtin_abort (); + + return 0; +} diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 097e4094095..22dc2c9e257 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -365,7 +365,17 @@ stream_out_histogram_value (struct output_block *ob, histogram_value hist) break; } for (i = 0; i < hist->n_counters; i++) - streamer_write_gcov_count (ob, hist->hvalue.counters[i]); + { + /* When user uses an unsigned type with a big value, constant converted + to gcov_type (a signed type) can be negative. */ + gcov_type value = hist->hvalue.counters[i]; + if (hist->type == HIST_TYPE_SINGLE_VALUE && i == 0) + ; + else + gcc_assert (value >= 0); + + streamer_write_gcov_count (ob, value); + } if (hist->hvalue.next) stream_out_histogram_value (ob, hist->hvalue.next); } -- 2.11.0