From: Richard Biener Date: Mon, 8 Dec 2025 10:06:54 +0000 (+0100) Subject: tree-optimization/123040 - handle nary -> ifn simplification in VN X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a6d911ca2e253297bc2f3be9d9db2a71a244a94;p=thirdparty%2Fgcc.git tree-optimization/123040 - handle nary -> ifn simplification in VN The following handles (by rejecting) simplifications that end up turning a VN NARY operation into a call which would be a VN REFERENCE and is unexpected and not handled. PR tree-optimization/123040 * tree-ssa-sccvn.cc (vn_nary_build_or_lookup_1): Only insert nary results. * g++.dg/torture/pr123040.C: New testcase. --- diff --git a/gcc/testsuite/g++.dg/torture/pr123040.C b/gcc/testsuite/g++.dg/torture/pr123040.C new file mode 100644 index 00000000000..3ba2d909f69 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr123040.C @@ -0,0 +1,61 @@ +// { dg-do compile } + +template +void CopyBytes(From from, To to) { + __builtin_memcpy(to, from, kBytes); +} +template void CopySameSize(From *from, To to) { + CopyBytes(from, to); +} +template using MakeUnsigned = char; +template struct Simd { + using T = Lane; + static constexpr int kPrivateLanes = N; + template using Rebind = Simd; +}; +template using TFromD = D::T; +template using Rebind = D::template Rebind; +template using RebindToUnsigned = Rebind, D>; +template struct Vec128 { + using PrivateT = T; + static constexpr int kPrivateN = 6; + T raw[16]; +}; +template using DFromV = Simd; +template Vec128, D::kPrivateLanes> Zero(D); +template using VFromD = decltype(Zero(D())); +template VFromD BitCast(D, VFrom v) { + VFromD to; + CopySameSize(&v, to.raw); + return to; +} +template Vec128 And(Vec128 b) { + Vec128 a; + DFromV d; + RebindToUnsigned du; + auto au(a); + auto bu = BitCast(du, b); + for (int i = 0; i < N; ++i) + au.raw[i] &= bu.raw[i]; + return au; +} +void Or(Vec128); +template void IfVecThenElse(Vec128 yes) { + Vec128 __trans_tmp_2 = And(yes); + Or(__trans_tmp_2); +} +template void IfThenElseZero(Vec128 yes) { + IfVecThenElse(yes); +} +Vec128 Abs_a; +char MaskedAbs___trans_tmp_5; +void MaskedAbs() { + Vec128 __trans_tmp_4; + for (int i = 0; i < 16; ++i) { + MaskedAbs___trans_tmp_5 = Abs_a.raw[i] ? -Abs_a.raw[i] : 0; + Abs_a.raw[i] = MaskedAbs___trans_tmp_5; + } + __trans_tmp_4 = Abs_a; + Vec128 __trans_tmp_3 = __trans_tmp_4; + IfThenElseZero(__trans_tmp_3); +} diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 09f92b2efc1..0c519cf4c21 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -2527,7 +2527,10 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert, else { tree val = vn_lookup_simplify_result (res_op); - if (!val && insert) + /* ??? In weird cases we can end up with internal-fn calls, + but this isn't expected so throw the result away. See + PR123040 for an example. */ + if (!val && insert && res_op->code.is_tree_code ()) { gimple_seq stmts = NULL; result = maybe_push_res_to_seq (res_op, &stmts);