From: H.J. Lu Date: Mon, 1 Dec 2025 02:05:44 +0000 (+0800) Subject: x86: Emit the TLS call after deleted instructions X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c44586acdc6e107de7ceea173aaaacd8b0525153;p=thirdparty%2Fgcc.git x86: Emit the TLS call after deleted instructions For a basic block with only deleted instructions: (code_label 348 23 349 45 3 (nil) [0 uses]) (note 349 348 436 45 [bb 45] NOTE_INSN_BASIC_BLOCK) (note 436 349 362 45 NOTE_INSN_DELETED) emit the TLS call after deleted instructions. gcc/ PR target/122906 * config/i386/i386-features.cc (ix86_emit_tls_call): Emit the TLS call after deleted instructions. gcc/testsuite/ PR target/122906 * g++.target/i386/pr122906-1.C: New test. Signed-off-by: H.J. Lu --- diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index f1f118d5b75..ce6f40b922c 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -3947,11 +3947,19 @@ ix86_emit_tls_call (rtx tls_set, x86_cse_kind kind, basic_block bb, (note 2 3 5 2 NOTE_INSN_FUNCTION_BEG) (debug_insn 5 2 16 2 (debug_marker) "x.c":6:3 -1 (nil)) + or a basic block with only deleted instructions: + + (code_label 348 23 349 45 3 (nil) [0 uses]) + (note 349 348 436 45 [bb 45] NOTE_INSN_BASIC_BLOCK) + (note 436 349 362 45 NOTE_INSN_DELETED) + */ gcc_assert (DEBUG_INSN_P (insn) || (NOTE_P (insn) && ((NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + || (NOTE_KIND (insn) + == NOTE_INSN_DELETED) || (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK)))); insn = NULL; diff --git a/gcc/testsuite/g++.target/i386/pr122906-1.C b/gcc/testsuite/g++.target/i386/pr122906-1.C new file mode 100644 index 00000000000..6c4be38d892 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr122906-1.C @@ -0,0 +1,1065 @@ +// { dg-do compile { target *-*-linux* } } +// { dg-options "-O3 -std=c++20 -ftrivial-auto-var-init=zero -march=x86-64-v3 -fPIC -w -mtls-dialect=gnu " } + +template using b = int; +template struct e; +struct m {}; +template struct aa; +template struct j; +using h = aa>; +template using a = h; +template using k = h; +template struct p { + d ad; +}; +struct ac {}; +template struct al; +template struct al { + typedef g &ah; +}; +template z ::i q(z); +struct w { + e *l; + al *>::ah operator*() { return *l; } + bool operator==(w) { return l; } +}; +template struct n { + using af = g[o]; +}; +template struct ak { + n::af am; +}; +void ab(); +template void ar(ai r, ac) { + ai ag; + for (; r != ag; ++r) + ab(), *r; +} +template void as(ai r, ac) { ar(r, q(r)); } +struct { + template void aj(ai r, ai) { as(r, q(r)); } +} ao; +namespace ap { +template struct bb { + static const bool ax = at; +}; +} // namespace ap +using ap::bb; +namespace av { +template struct c; +template struct c { + static const bool ax = au; + operator bb() { + void *bc; + return *reinterpret_cast *>(bc); + } +}; +template struct ae : c {}; +template struct ae : c {}; +namespace aw { +using namespace ap; +} +} // namespace av +namespace ap { +template struct bd { + typedef bd<1> bh; +}; +} // namespace ap +namespace av { +namespace aw { +template struct be; +template struct bn : bb {}; +template +struct bn : bn> {}; +template <> +struct bn, bb, bb, bb> : bb {}; +template , + typename az = bb, typename bl = bb> +struct br : bn {}; +} // namespace aw +template struct bi { + typedef aq h; +}; +template bi::h bf(); +template struct ba : c {}; +template struct ba : c {}; +template struct bk { + typedef aq const h; +}; +template struct bq { + typedef aq h; +}; +template struct bu { + typedef aq::h h; +}; +template struct by { + typedef bo ::ah h; +}; +template struct bm { + typedef aq h; +}; +template struct bm { + typedef aq h; +}; +namespace aw { +template struct bp { + typedef bg h; +}; +template struct bp { + typedef bj h; +}; +template struct cg { + typedef bp::h h; +}; +template struct bs { + typedef cg::h ::h h; +}; +template struct bx; +template +struct bx : bx> {}; +template <> +struct bx, bb, bb, bb> : bb {}; +template +struct bw : bx, bb, bb> {}; +} // namespace aw +template struct cb { + template static void ca(cc); + template static decltype(ca(bf())) cr(int); + template static int cr(...); + static const bool ax = sizeof(cr(0)) == 1; +}; +template struct cm { + static const bool ax = cb::ax; +}; +template struct cl { + typedef cm h; +}; +template struct ci { + typedef cl::h h; +}; +template struct co : ci::h {}; +template struct ce : c::ax> {}; +namespace aw { +template struct cf { + typedef aq h; +}; +} // namespace aw +template struct arg { + template struct apply { + typedef ck h; + }; +}; +template <> struct arg<2> { + template struct apply { + typedef cu h; + }; +}; +struct cj {}; +template struct cx : aw::bs, aw::cf> {}; +template struct cw : cx {}; +template +struct cn : aw::bs, ce>, aw::cf> {}; +template struct dd : aw::br, ce> {}; +template struct cz : cs, ct {}; +template struct da { + typedef cn::h category; + typedef aw::cg, category, cz>::h h; +}; +template +struct s : aw::bs, aw::cf, da> {}; +namespace aw { +template struct de : df::apply {}; +template +struct u : df::apply {}; +template +struct db : df::apply {}; +template struct bh { + typedef aq::bh h; +}; +template struct cv; +template +struct cv, ck, cu, dm> { + typedef db, ck, cu>::h h; +}; +template struct dh { + template struct apply { + typedef de::h>::h h; + }; +}; +template +struct cv, ck, cu, dm> { + typedef db, ck, cu>::h h; +}; +template struct dg { + template struct apply { + typedef u::h, + typename cv::h>::h h; + }; +}; +template struct di { + typedef aq::h h; +}; +template