mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
tree-optimization/111465 - bougs jump threading with no-copy src block
The following avoids to forward thread a path with a EDGE_NO_COPY_SRC_BLOCK block that became non-empty due to folding. PR tree-optimization/111465 * tree-ssa-threadupdate.cc (fwd_jt_path_registry::thread_block_1): Cancel the path when a EDGE_NO_COPY_SRC_BLOCK became non-empty. * g++.dg/torture/pr111465.C: New testcase.
This commit is contained in:
55
gcc/testsuite/g++.dg/torture/pr111465.C
Normal file
55
gcc/testsuite/g++.dg/torture/pr111465.C
Normal file
@@ -0,0 +1,55 @@
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options "-fno-exceptions --param=logical-op-non-short-circuit=0" }
|
||||
|
||||
typedef unsigned int location_t;
|
||||
const location_t MAX_LOCATION_T = 0x7FFFFFFF;
|
||||
struct line_maps {
|
||||
unsigned int info_ordinary;
|
||||
location_t *maps;
|
||||
unsigned int used;
|
||||
location_t *data;
|
||||
};
|
||||
inline location_t LINEMAPS_MACRO_LOWEST_LOCATION(const line_maps *set) {
|
||||
return set->used
|
||||
? set->maps[set->used - 1]
|
||||
: MAX_LOCATION_T + 1;
|
||||
}
|
||||
const location_t *linemap_lookup(const line_maps *set, location_t line) {
|
||||
int mn = set->info_ordinary;
|
||||
if (mn >= 0)
|
||||
if ((unsigned int)mn < set->used)
|
||||
return &set->maps[0];
|
||||
__builtin_unreachable();
|
||||
}
|
||||
bool linemap_location_from_macro_expansion_p(const class line_maps *set,
|
||||
location_t location) {
|
||||
if (location > MAX_LOCATION_T)
|
||||
location = set->data[location & MAX_LOCATION_T];
|
||||
return location >= LINEMAPS_MACRO_LOWEST_LOCATION(set);
|
||||
}
|
||||
void first_map_in_common_1(line_maps *set, location_t *loc0,
|
||||
location_t *loc1) {
|
||||
linemap_lookup(set, 0);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
int linemap_compare_locations(line_maps *set, location_t pre, location_t post) {
|
||||
bool pre_virtual_p;
|
||||
location_t l0 = pre, l1 = post;
|
||||
if (l0 > MAX_LOCATION_T)
|
||||
l0 = set->data[l0 & MAX_LOCATION_T];
|
||||
if (l1 > MAX_LOCATION_T)
|
||||
l1 = set->data[l1 & MAX_LOCATION_T];;
|
||||
if (l0 == l1)
|
||||
return 0;
|
||||
if ((pre_virtual_p = linemap_location_from_macro_expansion_p(set, l0)))
|
||||
l0 = set->data[l0 & MAX_LOCATION_T];
|
||||
if (linemap_location_from_macro_expansion_p(set, l1))
|
||||
l1 = set->data[l1 & MAX_LOCATION_T];
|
||||
if (l0 == l1)
|
||||
if (pre_virtual_p)
|
||||
first_map_in_common_1(set, &l0, &l1);
|
||||
if (l0 > MAX_LOCATION_T)
|
||||
if (l1 > MAX_LOCATION_T)
|
||||
l1 = set->data[l1 & MAX_LOCATION_T];
|
||||
return l1 - l0;
|
||||
}
|
||||
@@ -1454,6 +1454,19 @@ fwd_jt_path_registry::thread_block_1 (basic_block bb,
|
||||
|| ((*path)[1]->type == EDGE_COPY_SRC_BLOCK && joiners))
|
||||
continue;
|
||||
|
||||
/* When a NO_COPY_SRC block became non-empty cancel the path. */
|
||||
if (path->last ()->type == EDGE_NO_COPY_SRC_BLOCK)
|
||||
{
|
||||
auto gsi = gsi_start_nondebug_bb (path->last ()->e->src);
|
||||
if (!gsi_end_p (gsi)
|
||||
&& !is_ctrl_stmt (gsi_stmt (gsi)))
|
||||
{
|
||||
cancel_thread (path, "Non-empty EDGE_NO_COPY_SRC_BLOCK");
|
||||
e->aux = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
e2 = path->last ()->e;
|
||||
if (!e2 || noloop_only)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user