From f141050af5f5264a55bdaf4d70e42a8af7a9133a Mon Sep 17 00:00:00 2001 From: cmgCr Date: Fri, 6 Mar 2026 16:12:42 +0800 Subject: [PATCH 1/2] fix(compiler): shrink merged live range after erasing coalesced COPYs (#386) --- src/compiler/cgir/pass/register_coalescer.cpp | 13 +++++++----- .../spec_extra/coalescer_if_local_tee.wast | 21 +++++++++++++++++++ .../coalescer_memory_grow_local_tee.wast | 16 ++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tests/wast/spec_extra/coalescer_if_local_tee.wast create mode 100644 tests/wast/spec_extra/coalescer_memory_grow_local_tee.wast diff --git a/src/compiler/cgir/pass/register_coalescer.cpp b/src/compiler/cgir/pass/register_coalescer.cpp index d90d38908..c3c6e878c 100644 --- a/src/compiler/cgir/pass/register_coalescer.cpp +++ b/src/compiler/cgir/pass/register_coalescer.cpp @@ -2226,10 +2226,11 @@ class JoinVals { /// Erase any machine instructions that have been coalesced away. /// Add erased instructions to ErasedInstrs. /// Add foreign virtual registers to ShrinkRegs if their live range ended at - /// the erased instrs. + /// the erased instrs. Set ShrinkMainRange when erasing a COPY whose source + /// is part of the coalesced pair, so the merged interval gets shrunk. void eraseInstrs(SmallPtrSetImpl &ErasedInstrs, SmallVectorImpl &ShrinkRegs, - CgLiveInterval *LI = nullptr); + bool &ShrinkMainRange, CgLiveInterval *LI = nullptr); /// Remove liverange defs at places where implicit defs will be removed. void removeImplicitDefs(); @@ -3019,7 +3020,7 @@ void JoinVals::removeImplicitDefs() { void JoinVals::eraseInstrs(SmallPtrSetImpl &ErasedInstrs, SmallVectorImpl &ShrinkRegs, - CgLiveInterval *LI) { + bool &ShrinkMainRange, CgLiveInterval *LI) { for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) { // Get the def location before markUnused() below invalidates it. CgVNInfo *VNI = LR.getValNumInfo(i); @@ -3101,6 +3102,8 @@ void JoinVals::eraseInstrs(SmallPtrSetImpl &ErasedInstrs, if (Register::isVirtualRegister(Reg) && Reg != CP.getSrcReg() && Reg != CP.getDstReg()) ShrinkRegs.push_back(Reg); + else if (Register::isVirtualRegister(Reg) && MI->allDefsAreDead()) + ShrinkMainRange = true; } ErasedInstrs.insert(MI); LLVM_DEBUG(dbgs() << "\t\terased:\t" << Def << '\t' << *MI); @@ -3294,8 +3297,8 @@ bool CgRegisterCoalescer::joinVirtRegs(CgCoalescerPair &CP) { // Erase COPY and IMPLICIT_DEF instructions. This may cause some external // registers to require trimming. SmallVector ShrinkRegs; - LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, &LHS); - RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs); + LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, ShrinkMainRange, &LHS); + RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, ShrinkMainRange); while (!ShrinkRegs.empty()) shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val())); diff --git a/tests/wast/spec_extra/coalescer_if_local_tee.wast b/tests/wast/spec_extra/coalescer_if_local_tee.wast new file mode 100644 index 000000000..2177c107c --- /dev/null +++ b/tests/wast/spec_extra/coalescer_if_local_tee.wast @@ -0,0 +1,21 @@ +(module + (type (;0;) (func (result f64))) + (type (;1;) (func (result i64))) + (func (;0;) (type 0) (result f64) + (local f64) + i32.const 1 + if ;; label = @1 + end + call 1 + local.get 0 + local.set 0 + drop + f64.const 0x0p+0 (;=0;) + local.tee 0 + local.get 0 + i32.trunc_f64_u + drop) + (func (;1;) (type 1) (result i64) + i64.const 1) + (export "to_test" (func 0))) +(assert_return (invoke "to_test") (f64.const 0)) diff --git a/tests/wast/spec_extra/coalescer_memory_grow_local_tee.wast b/tests/wast/spec_extra/coalescer_memory_grow_local_tee.wast new file mode 100644 index 000000000..ca5877c0e --- /dev/null +++ b/tests/wast/spec_extra/coalescer_memory_grow_local_tee.wast @@ -0,0 +1,16 @@ +(module + (type (;0;) (func (param i32) (result i64))) + (type (;1;) (func (result i64))) + (func (;0;) (type 1) (result i64) + (local i32) + i32.const -1812402867 + memory.grow + local.get 0 + local.set 0 + local.tee 0 + drop + local.get 0 + i64.load32_u offset=55218920 align=1) + (memory (;0;) 1) + (export "to_test" (func 0))) +(assert_trap (invoke "to_test") "out of bounds memory access") From 8d1c90395a638d4bee7a0ed0af084b1b5359096c Mon Sep 17 00:00:00 2001 From: cmgCr Date: Fri, 13 Mar 2026 17:50:56 +0800 Subject: [PATCH 2/2] ci: remove auto-assign workflow --- .github/workflows/auto-assign.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/auto-assign.yml diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml deleted file mode 100644 index 1ed248019..000000000 --- a/.github/workflows/auto-assign.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Auto Assign -on: - issues: - types: [opened] - pull_request: - types: [opened] -jobs: - run: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: 'Auto-assign issue' - uses: pozil/auto-assign-issue@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: zoowii - numOfAssignee: 1