https://gcc.gnu.org/g:06765f2e0fc4991e08adda7f72902edfb7e70fbb
commit r16-6915-g06765f2e0fc4991e08adda7f72902edfb7e70fbb Author: Richard Biener <[email protected]> Date: Tue Jan 20 10:24:20 2026 +0100 tree-optimization/123729 - fix reduction epilog flowing into abnormal edge When we vectorize a reduction and the reduction value flows across an abnormal edge we have to make sure to mark the final SSA properly. The following serves as a recipie how to avoid blindly copying SSA_NAME_OCCURS_IN_ABNORMAL_PHI but instead set it when needed during use replacement. PR tree-optimization/123729 * tree-vect-loop.cc (vect_create_epilog_for_reduction): Set SSA_NAME_OCCURS_IN_ABNORMAL_PHI if the reduction flows across an abnomal edge. * g++.dg/torture/pr123729.C: New testcase. Diff: --- gcc/testsuite/g++.dg/torture/pr123729.C | 60 +++++++++++++++++++++++++++++++++ gcc/tree-vect-loop.cc | 11 +++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/g++.dg/torture/pr123729.C b/gcc/testsuite/g++.dg/torture/pr123729.C new file mode 100644 index 000000000000..1e12c680f299 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr123729.C @@ -0,0 +1,60 @@ +// { dg-do compile } +// { dg-additional-options "-std=gnu++20" } + +#include <csetjmp> +#include <iostream> + +template <typename T> struct A { using type = int; }; +template <typename F, typename... G> struct B {}; +template <typename F> struct B<F> { using type = F; }; +struct { + template <typename... F, + typename Overload = typename B<typename A<F>::type...>::type> + int operator()(F...) { + int iArrFld_0_0; + for (int i = 7; i < 28; ++i) + ; + int i1 = 3; + try { + for (int i = 7; i < 28; ++i) { + for (int j = 0; j < 7; ++j) + if (iArrFld_0_0 == 0) { + for (int k = 0; k < 20000; ++k) + std::cout << "Hello, world!" << std::endl; + } + jmp_buf env2; + for (int i2 = 16; i2 < 350; ++i2) + for (int j2 = 1; j2 < 75; ++j2) + for (int k2 = 0; k2 < 16; ++k2) { + int temp2 = i2 + j2 + k2; + int mod2 = temp2 % 8; + { + setjmp(env2) == 0; + ; + } + } + } + } catch (const std::exception &e) { + } + auto lambda = [](int x) { + return [x](int y) { + int z = 0; + if (y > 0) + z = 1; + return z + x; + }; + }; + for (int i = 0; i < 1000; ++i) { + int m = 0; + auto f = lambda(i); + for (int j = 0; j < 100; ++j) + m += f(j); + i1 += m; + } + std::cout << "Final value of i1: " << i1 << std::endl; + return 0; + } +} a; +int main() { + auto f = a([] {}); +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 9c2345ce955d..c8b9c6268c84 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -6287,8 +6287,17 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, scalar_result = scalar_results[k]; FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name) { + gphi *use_phi = dyn_cast <gphi *> (use_stmt); FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) - SET_USE (use_p, scalar_result); + { + if (use_phi + && (phi_arg_edge_from_use (use_p)->flags & EDGE_ABNORMAL)) + { + gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_name)); + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (scalar_result) = 1; + } + SET_USE (use_p, scalar_result); + } update_stmt (use_stmt); } }
