Index: llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -2154,8 +2154,27 @@ } if (NewOpc != -1) { + // removeOperand doesn't fixup tied operand indexes at it goes, so + // it asserts. Untie vdst_in for now and retie them afterwards. + int VDstIn = AMDGPU::getNamedOperandIdx(Opc, + AMDGPU::OpName::vdst_in); + bool TiedVDst = VDstIn != -1 && + MI->getOperand(VDstIn).isReg() && + MI->getOperand(VDstIn).isTied(); + if (TiedVDst) + MI->untieRegOperand(VDstIn); + MI->removeOperand( AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::saddr)); + + if (TiedVDst) { + int NewVDst = + AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst); + int NewVDstIn = + AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in); + assert (NewVDst != -1 && NewVDstIn != -1 && "Must be tied!"); + MI->tieOperands(NewVDst, NewVDstIn); + } MI->setDesc(TII->get(NewOpc)); return; } Index: llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=amdgcn -mcpu=gfx1100 < %s | FileCheck --check-prefix=GCN %s + +define amdgpu_kernel void @tied_operand_test() local_unnamed_addr { +; GCN-LABEL: tied_operand_test: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: scratch_load_u16 [[LDRESULT:v[0-9]+]], off, off offset:4 +; GCN-NEXT: s_waitcnt vmcnt(0) +; GCN-NEXT: ds_store_b16 v{{[0-9]+}}, [[LDRESULT]] +; GCN-NEXT: s_endpgm +entry: + %scratch = alloca i16, align 4, addrspace(5) + %cond = select i1 undef, i16 addrspace(5)* %scratch, i16 addrspace(5)* undef + %spec.select = select i1 undef, i16 addrspace(5)* %cond, i16 addrspace(5)* %scratch + %dead.load = load i16, i16 addrspace(5)* %spec.select, align 2 + %flat.scratch.load = load i16, i16 addrspace(5)* %scratch, align 4 + store i16 %flat.scratch.load, i16 addrspace(3)* undef, align 2 + ret void +}