[llvm-branch-commits] [llvm] 5d16173 - MIPS/expandAtomicBinOp: Remove tailing kill dead register operands (#186055)

Cullen Rhodes via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Apr 17 02:36:32 PDT 2026


Author: YunQiang Su
Date: 2026-04-17T09:36:24Z
New Revision: 5d161731998c2537c61fb3d5d7bc74795210e0fd

URL: https://github.com/llvm/llvm-project/commit/5d161731998c2537c61fb3d5d7bc74795210e0fd
DIFF: https://github.com/llvm/llvm-project/commit/5d161731998c2537c61fb3d5d7bc74795210e0fd.diff

LOG: MIPS/expandAtomicBinOp: Remove tailing kill dead register operands (#186055)

Some trailing kill/dead register operands may added by
MachineInstr::addRegisterKilled or MachineInstr::addRegisterDead, which
uses the overlap registers same with the operand 1-4.

Let's remove them here as only 5 operands are assert existing.

(cherry picked from commit d2c6e4c11da26c6452d4131cf5dd8de9a5e06e97)

Added: 
    llvm/test/CodeGen/Mips/atomic-min-max-LiveVariables.ll

Modified: 
    llvm/lib/Target/Mips/MipsExpandPseudo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 78f2e5db40f9d..b39eb9863b042 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -882,6 +882,33 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
   assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
   assert((OldVal != Incr) && "Clobbered the wrong reg!");
   if (IsMin || IsMax) {
+    // Remove trailing kill/dead register operands added by
+    // MachineInstr::addRegisterKilled. These are super-register markers that
+    // must correspond to one of the physical registers in operands 1-4.
+    // The kill/dead markers may also appear on preceding subregs.
+    const TargetRegisterInfo *TRI = STI->getRegisterInfo();
+    while (I->getNumOperands() > 5) {
+      auto &Op = I->getOperand(I->getNumOperands() - 1);
+      // Check if this register overlaps with any physical register in
+      // operands 1-4 that has kill/dead marker (i.e., it's a super-register
+      // marker for subregs).
+      bool HasOverlapWithKill = false;
+      for (unsigned i = 1; i <= 4; ++i) {
+        auto &RefOp = I->getOperand(i);
+        if (RefOp.isReg() && RefOp.getReg().isPhysical() &&
+            TRI->regsOverlap(Op.getReg(), RefOp.getReg()) &&
+            (RefOp.isKill() || RefOp.isDead())) {
+          HasOverlapWithKill = true;
+          break;
+        }
+      }
+      // Remove if HasOverlapWithKill is true or Op has kill/dead marker.
+      bool HasKillOrDead = Op.isReg() && Op.getReg().isPhysical() &&
+                           (Op.isKill() || Op.isDead());
+      if (!HasOverlapWithKill && !HasKillOrDead)
+        break;
+      I->removeOperand(I->getNumOperands() - 1);
+    }
 
     assert(I->getNumOperands() == 5 &&
            "Atomics min|max|umin|umax use an additional register");

diff  --git a/llvm/test/CodeGen/Mips/atomic-min-max-LiveVariables.ll b/llvm/test/CodeGen/Mips/atomic-min-max-LiveVariables.ll
new file mode 100644
index 0000000000000..d07c7f61ece41
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/atomic-min-max-LiveVariables.ll
@@ -0,0 +1,131 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mips64-elf -O2 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R2-O2
+; RUN: llc -mtriple=mips64-elf -O3 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R2-O3
+; RUN: llc -mtriple=mips64el-elf -O2 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R2-O2
+; RUN: llc -mtriple=mips64el-elf -O3 -mcpu=mips64r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R2-O3
+; RUN: llc -mtriple=mips64-elf -O2 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R6-O2
+; RUN: llc -mtriple=mips64-elf -O3 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R6-O3
+; RUN: llc -mtriple=mips64el-elf -O2 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R6-O2
+; RUN: llc -mtriple=mips64el-elf -O3 -mcpu=mips64r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=R6-O3
+
+declare void @exit(i32) noreturn
+
+define void @test_func(ptr %ptr, i32 %val, i1 %cond) nounwind {
+; R2-O2-LABEL: test_func:
+; R2-O2:       # %bb.0: # %entry
+; R2-O2-NEXT:    move $2, $4
+; R2-O2-NEXT:    sll $1, $6, 0
+; R2-O2-NEXT:    andi $1, $1, 1
+; R2-O2-NEXT:    beqz $1, .LBB0_4
+; R2-O2-NEXT:    sll $4, $5, 0
+; R2-O2-NEXT:  # %bb.1: # %bb5
+; R2-O2-NEXT:    .insn
+; R2-O2-NEXT:  .LBB0_2: # %bb5
+; R2-O2-NEXT:    # =>This Inner Loop Header: Depth=1
+; R2-O2-NEXT:    ll $1, 0($2)
+; R2-O2-NEXT:    sltu $5, $1, $4
+; R2-O2-NEXT:    move $3, $1
+; R2-O2-NEXT:    movn $3, $4, $5
+; R2-O2-NEXT:    sc $3, 0($2)
+; R2-O2-NEXT:    beqz $3, .LBB0_2
+; R2-O2-NEXT:    nop
+; R2-O2-NEXT:  # %bb.3: # %bb5
+; R2-O2-NEXT:    jr $ra
+; R2-O2-NEXT:    nop
+; R2-O2-NEXT:  .LBB0_4: # %bb4
+; R2-O2-NEXT:    daddiu $sp, $sp, -16
+; R2-O2-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; R2-O2-NEXT:    jal exit
+; R2-O2-NEXT:    nop
+;
+; R2-O3-LABEL: test_func:
+; R2-O3:       # %bb.0: # %entry
+; R2-O3-NEXT:    sll $1, $6, 0
+; R2-O3-NEXT:    move $2, $4
+; R2-O3-NEXT:    andi $1, $1, 1
+; R2-O3-NEXT:    beqz $1, .LBB0_4
+; R2-O3-NEXT:    sll $4, $5, 0
+; R2-O3-NEXT:  # %bb.1: # %bb5
+; R2-O3-NEXT:    .insn
+; R2-O3-NEXT:  .LBB0_2: # %bb5
+; R2-O3-NEXT:    # =>This Inner Loop Header: Depth=1
+; R2-O3-NEXT:    ll $1, 0($2)
+; R2-O3-NEXT:    sltu $5, $1, $4
+; R2-O3-NEXT:    move $3, $1
+; R2-O3-NEXT:    movn $3, $4, $5
+; R2-O3-NEXT:    sc $3, 0($2)
+; R2-O3-NEXT:    beqz $3, .LBB0_2
+; R2-O3-NEXT:    nop
+; R2-O3-NEXT:  # %bb.3: # %bb5
+; R2-O3-NEXT:    jr $ra
+; R2-O3-NEXT:    nop
+; R2-O3-NEXT:  .LBB0_4: # %bb4
+; R2-O3-NEXT:    daddiu $sp, $sp, -16
+; R2-O3-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; R2-O3-NEXT:    jal exit
+; R2-O3-NEXT:    nop
+;
+; R6-O2-LABEL: test_func:
+; R6-O2:       # %bb.0: # %entry
+; R6-O2-NEXT:    move $2, $4
+; R6-O2-NEXT:    sll $1, $6, 0
+; R6-O2-NEXT:    andi $1, $1, 1
+; R6-O2-NEXT:    beqz $1, .LBB0_4
+; R6-O2-NEXT:    sll $4, $5, 0
+; R6-O2-NEXT:  # %bb.1: # %bb5
+; R6-O2-NEXT:    .insn
+; R6-O2-NEXT:  .LBB0_2: # %bb5
+; R6-O2-NEXT:    # =>This Inner Loop Header: Depth=1
+; R6-O2-NEXT:    ll $1, 0($2)
+; R6-O2-NEXT:    sltu $5, $1, $4
+; R6-O2-NEXT:    seleqz $3, $1, $5
+; R6-O2-NEXT:    selnez $5, $4, $5
+; R6-O2-NEXT:    or $3, $3, $5
+; R6-O2-NEXT:    sc $3, 0($2)
+; R6-O2-NEXT:    beqzc $3, .LBB0_2
+; R6-O2-NEXT:    nop
+; R6-O2-NEXT:  # %bb.3: # %bb5
+; R6-O2-NEXT:    jrc $ra
+; R6-O2-NEXT:  .LBB0_4: # %bb4
+; R6-O2-NEXT:    daddiu $sp, $sp, -16
+; R6-O2-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; R6-O2-NEXT:    jal exit
+; R6-O2-NEXT:    nop
+;
+; R6-O3-LABEL: test_func:
+; R6-O3:       # %bb.0: # %entry
+; R6-O3-NEXT:    sll $1, $6, 0
+; R6-O3-NEXT:    move $2, $4
+; R6-O3-NEXT:    andi $1, $1, 1
+; R6-O3-NEXT:    beqz $1, .LBB0_4
+; R6-O3-NEXT:    sll $4, $5, 0
+; R6-O3-NEXT:  # %bb.1: # %bb5
+; R6-O3-NEXT:    .insn
+; R6-O3-NEXT:  .LBB0_2: # %bb5
+; R6-O3-NEXT:    # =>This Inner Loop Header: Depth=1
+; R6-O3-NEXT:    ll $1, 0($2)
+; R6-O3-NEXT:    sltu $5, $1, $4
+; R6-O3-NEXT:    seleqz $3, $1, $5
+; R6-O3-NEXT:    selnez $5, $4, $5
+; R6-O3-NEXT:    or $3, $3, $5
+; R6-O3-NEXT:    sc $3, 0($2)
+; R6-O3-NEXT:    beqzc $3, .LBB0_2
+; R6-O3-NEXT:    nop
+; R6-O3-NEXT:  # %bb.3: # %bb5
+; R6-O3-NEXT:    jrc $ra
+; R6-O3-NEXT:  .LBB0_4: # %bb4
+; R6-O3-NEXT:    daddiu $sp, $sp, -16
+; R6-O3-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; R6-O3-NEXT:    jal exit
+; R6-O3-NEXT:    nop
+entry:
+  br i1 %cond, label %bb5, label %bb4
+
+bb4:
+  call void @exit(i32 %val)
+  unreachable
+
+bb5:
+  %old = atomicrmw umax ptr %ptr, i32 %val monotonic, align 4
+  ret void
+}


        


More information about the llvm-branch-commits mailing list