diff options
author | Jørgen Kvalsvik <j@lambda.is> | 2024-04-08 15:19:55 +0200 |
---|---|---|
committer | Jørgen Kvalsvik <j@lambda.is> | 2024-04-09 09:57:42 +0200 |
commit | a2447556a5405d2cde20afc134b90cd1d199ce04 (patch) | |
tree | ff9cb68046913db08c85b4332554a204f28b20dc /gcc | |
parent | 2daeb89d6f025d6daf7e560575863b3280120be8 (diff) | |
download | gcc-a2447556a5405d2cde20afc134b90cd1d199ce04.zip gcc-a2447556a5405d2cde20afc134b90cd1d199ce04.tar.gz gcc-a2447556a5405d2cde20afc134b90cd1d199ce04.tar.bz2 |
Generate constant at start of loop, without UB
Generating the constants used for recording the edges taken for
condition coverage would trigger undefined behavior when an expression
had exactly 64 (== sizeof (1ULL)) conditions, as it would generate the
constant for the next iteration at the end of the loop body, even if there
was never a next iteration. By moving the check and constant generation
to the top of the loop and hoisting the increment flag there is no
opportunity for UB.
PR middle-end/114627
gcc/ChangeLog:
* tree-profile.cc (instrument_decisions): Generate constant
at the start of loop.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/tree-profile.cc | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc index f9d727b..b85111624 100644 --- a/gcc/tree-profile.cc +++ b/gcc/tree-profile.cc @@ -1049,6 +1049,7 @@ instrument_decisions (array_slice<basic_block> expr, size_t condno, zerocounter[2] = zero; unsigned xi = 0; + bool increment = false; tree rhs = build_int_cst (gcov_type_node, 1ULL << xi); for (basic_block current : expr) { @@ -1057,7 +1058,14 @@ instrument_decisions (array_slice<basic_block> expr, size_t condno, candidates.safe_push (zerocounter); counters prev = resolve_counters (candidates); - int increment = 0; + if (increment) + { + xi += 1; + gcc_checking_assert (xi < sizeof (uint64_t) * BITS_PER_UNIT); + rhs = build_int_cst (gcov_type_node, 1ULL << xi); + increment = false; + } + for (edge e : current->succs) { counters next = prev; @@ -1072,7 +1080,7 @@ instrument_decisions (array_slice<basic_block> expr, size_t condno, tree m = build_int_cst (gcov_type_node, masks[2*xi + k]); next[2] = emit_bitwise_op (e, prev[2], BIT_IOR_EXPR, m); } - increment = 1; + increment = true; } else if (e->flags & EDGE_COMPLEX) { @@ -1085,11 +1093,13 @@ instrument_decisions (array_slice<basic_block> expr, size_t condno, } table.get_or_insert (e->dest).safe_push (next); } - xi += increment; - if (increment) - rhs = build_int_cst (gcov_type_node, 1ULL << xi); } + /* Since this is also the return value, the number of conditions, make sure + to include the increment of the last basic block. */ + if (increment) + xi += 1; + gcc_assert (xi == bitmap_count_bits (core)); const tree relaxed = build_int_cst (integer_type_node, MEMMODEL_RELAXED); |