]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
target/123137 - improve TLS call placement validity check
authorRichard Biener <rguenther@suse.de>
Wed, 18 Feb 2026 09:05:02 +0000 (10:05 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 18 Feb 2026 14:20:44 +0000 (15:20 +0100)
When we search for a point in an inseration candidate block that has
incoming live call clobbered regs we look for REG_DEAD notes of
those and indication of FLAGS reg becoming live.  But we consider
insns like

(insn 807 805 6 2 (parallel [
            (set (subreg:SI (reg:HI 509) 0)
                (lshiftrt:SI (reg:SI 514)
                    (const_int 16 [0x10])))
            (clobber (reg:CC 17 flags))
        ]) "/home/packages/tmp/onednn-3.9.1+ds/src/cpu/x64/brgemm/jit_brgemm_amx_uker.cpp":1891:25 1213 {*lshrsi3_1}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_DEAD (reg:SI 514)
            (nil))))

making the FLAGS_REG live despite the REG_UNUSED note or the setter
being a CLOBBER.  The following optimizes this by in turn honoring
REG_UNUSED for FLAGS_REG, pruning it immediately again.

This reduces required expensive iteration to other candidate BBs,
reducing compile-time for the testcase in the PR from hours to 6s.

PR target/123137
* config/i386/i386-features.cc (ix86_emit_tls_call): Improve
local FLAGS_REG liveness calculation.

* g++.dg/torture/pr124137.C: New testcase.

gcc/config/i386/i386-features.cc
gcc/testsuite/g++.dg/torture/pr124137.C [new file with mode: 0644]

index 4e94b2f742ee9082c5c6a204a27163b4bdddf82b..0e4fdcd285391ff52ece30cfd480a7fc02215ed9 100644 (file)
@@ -4083,7 +4083,9 @@ ix86_emit_tls_call (rtx tls_set, x86_cse_kind kind, basic_block bb,
 
          rtx link;
          for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-           if (REG_NOTE_KIND (link) == REG_DEAD
+           if ((REG_NOTE_KIND (link) == REG_DEAD
+                || (REG_NOTE_KIND (link) == REG_UNUSED
+                    && REGNO (XEXP (link, 0)) == FLAGS_REG))
                && REG_P (XEXP (link, 0)))
              {
                /* Mark the live caller-saved register as dead.  */
diff --git a/gcc/testsuite/g++.dg/torture/pr124137.C b/gcc/testsuite/g++.dg/torture/pr124137.C
new file mode 100644 (file)
index 0000000..538433e
--- /dev/null
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-require-effective-target fpic }
+// { dg-additional-options "-fPIC" }
+
+inline int &GetErrorRef() {
+  thread_local int err;
+  return err;
+}
+int SetError_err;
+bool isREG___trans_tmp_4;
+struct Operand {
+  int : 6;
+  int kind_ : 10;
+  int bit_ : 14;
+protected:
+  int : 11;
+public:
+  bool isREG(int bit) {
+    isREG___trans_tmp_4 = kind_ && bit_ & bit;
+    return isREG___trans_tmp_4;
+  }
+  int getBit() { return bit_; }
+};
+struct Reg : Operand {
+} index_, fp8_to_f16_upconvert_to_vnni_reg_data;
+enum { i32e = 4 };
+struct RegExp {
+  RegExp(Reg &r) {
+    if (r.isREG(i32e))
+      GetErrorRef() = SetError_err;
+    if (r.getBit())
+      index_ = r;
+  }
+};
+struct X {
+  void operator[](RegExp);
+} ptr;
+void jit_brgemm_amx_uker_base_tfp8_to_f16_upconvert_to_vnni(Reg reg_buf) {
+  RegExp __trans_tmp_3 = fp8_to_f16_upconvert_to_vnni_reg_data;
+  ptr[reg_buf];
+}