aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJørgen Kvalsvik <j@lambda.is>2024-04-08 15:19:55 +0200
committerJørgen Kvalsvik <j@lambda.is>2024-04-09 09:57:42 +0200
commita2447556a5405d2cde20afc134b90cd1d199ce04 (patch)
treeff9cb68046913db08c85b4332554a204f28b20dc /gcc
parent2daeb89d6f025d6daf7e560575863b3280120be8 (diff)
downloadgcc-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.cc20
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);