diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1582,47 +1582,55 @@ } if (AllUsesCopied) { - bool ReplacedAllUntiedUses = false; - if (!IsEarlyClobber) { - // Replace other (un-tied) uses of regB with LastCopiedReg. - ReplacedAllUntiedUses = true; - for (MachineOperand &MO : MI->operands()) { - if (MO.isReg() && MO.getReg() == RegB && MO.isUse()) { - if (MO.getSubReg() == SubRegB) { - if (MO.isKill()) { - MO.setIsKill(false); - RemovedKillFlag = true; - } - MO.setReg(LastCopiedReg); - MO.setSubReg(0); - } else { - ReplacedAllUntiedUses = false; + LaneBitmask RemainingUses = LaneBitmask::getNone(); + // Replace other (un-tied) uses of regB with LastCopiedReg. + for (MachineOperand &MO : MI->operands()) { + if (MO.isReg() && MO.getReg() == RegB && MO.isUse()) { + if (MO.getSubReg() == SubRegB && !IsEarlyClobber) { + if (MO.isKill()) { + MO.setIsKill(false); + RemovedKillFlag = true; } + MO.setReg(LastCopiedReg); + MO.setSubReg(0); + } else { + RemainingUses |= TRI->getSubRegIndexLaneMask(MO.getSubReg()); } } } // Update live variables for regB. - if (RemovedKillFlag && ReplacedAllUntiedUses && - LV && LV->getVarInfo(RegB).removeKill(*MI)) { + if (RemovedKillFlag && RemainingUses.none() && LV && + LV->getVarInfo(RegB).removeKill(*MI)) { MachineBasicBlock::iterator PrevMI = MI; --PrevMI; LV->addVirtualRegisterKilled(RegB, *PrevMI); } - if (RemovedKillFlag && ReplacedAllUntiedUses) + if (RemovedKillFlag && RemainingUses.none()) SrcRegMap[LastCopiedReg] = RegB; // Update LiveIntervals. if (LIS) { - LiveInterval &LI = LIS->getInterval(RegB); - SlotIndex MIIdx = LIS->getInstructionIndex(*MI); - LiveInterval::const_iterator I = LI.find(MIIdx); - assert(I != LI.end() && "RegB must be live-in to use."); + SlotIndex UseIdx = LIS->getInstructionIndex(*MI); + auto Shrink = [=](LiveRange &LR, LaneBitmask LaneMask) { + LiveRange::Segment *S = LR.getSegmentContaining(LastCopyIdx); + if (!S) + return true; + if ((LaneMask & RemainingUses).any()) + return false; + if (S->end.getBaseIndex() != UseIdx) + return false; + S->end = LastCopyIdx; + return true; + }; - SlotIndex UseIdx = MIIdx.getRegSlot(IsEarlyClobber); - if (I->end == UseIdx) - LI.removeSegment(LastCopyIdx, UseIdx); + LiveInterval &LI = LIS->getInterval(RegB); + bool ShrinkLI = true; + for (auto &S : LI.subranges()) + ShrinkLI &= Shrink(S, S.LaneMask); + if (ShrinkLI) + Shrink(LI, LaneBitmask::getAll()); } } else if (RemovedKillFlag) { // Some tied uses of regB matched their destination registers, so diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.set.inactive.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -early-live-intervals -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s define amdgpu_kernel void @set_inactive(i32 addrspace(1)* %out, i32 %in) { ; GCN-LABEL: set_inactive: diff --git a/llvm/test/CodeGen/AMDGPU/operand-folding.ll b/llvm/test/CodeGen/AMDGPU/operand-folding.ll --- a/llvm/test/CodeGen/AMDGPU/operand-folding.ll +++ b/llvm/test/CodeGen/AMDGPU/operand-folding.ll @@ -1,4 +1,5 @@ ; RUN: llc -march=amdgcn -mcpu=tahiti -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -march=amdgcn -mcpu=tahiti -verify-machineinstrs -early-live-intervals < %s | FileCheck %s ; CHECK-LABEL: {{^}}fold_sgpr: ; CHECK: v_add_i32_e32 v{{[0-9]+}}, vcc, s diff --git a/llvm/test/CodeGen/Hexagon/addh.ll b/llvm/test/CodeGen/Hexagon/addh.ll --- a/llvm/test/CodeGen/Hexagon/addh.ll +++ b/llvm/test/CodeGen/Hexagon/addh.ll @@ -1,4 +1,5 @@ ; RUN: llc -march=hexagon < %s | FileCheck %s +; RUN: llc -march=hexagon -early-live-intervals -verify-machineinstrs < %s | FileCheck %s ; CHECK: r{{[0-9]+}} = add(r{{[0-9]+}}.{{L|l}},r{{[0-9]+}}.{{L|l}}) define i64 @test_cast(i64 %arg0, i16 zeroext %arg1, i16 zeroext %arg2) nounwind readnone { diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll @@ -4,6 +4,11 @@ ; RUN: llc -mtriple=riscv64 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=2 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX2 ; RUN: llc -mtriple=riscv64 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=1 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX1 +; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=2 -early-live-intervals -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX2 +; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=1 -early-live-intervals -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX1 +; RUN: llc -mtriple=riscv64 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=2 -early-live-intervals -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX2 +; RUN: llc -mtriple=riscv64 -mattr=+m,+experimental-v --riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=1 -early-live-intervals -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LMULMAX1 + define @insert_nxv8i32_v2i32_0( %vec, <2 x i32>* %svp) { ; CHECK-LABEL: insert_nxv8i32_v2i32_0: ; CHECK: # %bb.0: