aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-09-19 12:36:04 +0200
committerRichard Biener <rguenther@suse.de>2023-09-19 13:23:40 +0200
commit564ecb7d5afb0bb4eb39285ce65c631490e37dce (patch)
tree8915cc1352a9f652a79ee258262280d06a44cd3b /gcc
parent836e2cff7d9e4c06bf8ffd7e2df5dd134d8a22c2 (diff)
downloadgcc-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.C55
-rw-r--r--gcc/tree-ssa-threadupdate.cc13
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)
{