[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