diff options
author | Richard Biener <rguenther@suse.de> | 2023-09-19 12:36:04 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-09-19 13:23:40 +0200 |
commit | 564ecb7d5afb0bb4eb39285ce65c631490e37dce (patch) | |
tree | 8915cc1352a9f652a79ee258262280d06a44cd3b /gcc | |
parent | 836e2cff7d9e4c06bf8ffd7e2df5dd134d8a22c2 (diff) | |
download | gcc-564ecb7d5afb0bb4eb39285ce65c631490e37dce.zip gcc-564ecb7d5afb0bb4eb39285ce65c631490e37dce.tar.gz gcc-564ecb7d5afb0bb4eb39285ce65c631490e37dce.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr111465.C | 55 | ||||
-rw-r--r-- | gcc/tree-ssa-threadupdate.cc | 13 |
2 files changed, 68 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/pr111465.C b/gcc/testsuite/g++.dg/torture/pr111465.C new file mode 100644 index 0000000..8f2577a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr111465.C @@ -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; +} diff --git a/gcc/tree-ssa-threadupdate.cc b/gcc/tree-ssa-threadupdate.cc index a5b9a00..86fe8aa 100644 --- a/gcc/tree-ssa-threadupdate.cc +++ b/gcc/tree-ssa-threadupdate.cc @@ -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) { |