diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -88,19 +88,21 @@ struct FrameIndexOperand { std::string Name; unsigned ID; + /// Index in StackObjects vector. + unsigned Idx; bool IsFixed; - FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) - : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} + FrameIndexOperand(StringRef Name, unsigned ID, unsigned Idx, bool IsFixed) + : Name(Name.str()), ID(ID), Idx(Idx), IsFixed(IsFixed) {} /// Return an ordinary stack object reference. - static FrameIndexOperand create(StringRef Name, unsigned ID) { - return FrameIndexOperand(Name, ID, /*IsFixed=*/false); + static FrameIndexOperand create(StringRef Name, unsigned ID, unsigned Idx) { + return FrameIndexOperand(Name, ID, Idx, /*IsFixed=*/false); } /// Return a fixed stack object reference. - static FrameIndexOperand createFixed(unsigned ID) { - return FrameIndexOperand("", ID, /*IsFixed=*/true); + static FrameIndexOperand createFixed(unsigned ID, unsigned Idx) { + return FrameIndexOperand("", ID, Idx, /*IsFixed=*/true); } }; @@ -368,51 +370,55 @@ const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); // Process fixed stack objects. + assert(YMF.FixedStackObjects.empty() && "FixedStackObjects is not empty!"); unsigned ID = 0; - for (int I = MFI.getObjectIndexBegin(); I < 0; ++I, ++ID) { - if (MFI.isDeadObjectIndex(I)) + for (int Idx = MFI.getObjectIndexBegin(); Idx < 0; ++Idx, ++ID) { + if (MFI.isDeadObjectIndex(Idx)) continue; yaml::FixedMachineStackObject YamlObject; YamlObject.ID = ID; - YamlObject.Type = MFI.isSpillSlotObjectIndex(I) + YamlObject.Type = MFI.isSpillSlotObjectIndex(Idx) ? yaml::FixedMachineStackObject::SpillSlot : yaml::FixedMachineStackObject::DefaultType; - YamlObject.Offset = MFI.getObjectOffset(I); - YamlObject.Size = MFI.getObjectSize(I); - YamlObject.Alignment = MFI.getObjectAlign(I); - YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I); - YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); - YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); + YamlObject.Offset = MFI.getObjectOffset(Idx); + YamlObject.Size = MFI.getObjectSize(Idx); + YamlObject.Alignment = MFI.getObjectAlign(Idx); + YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(Idx); + YamlObject.IsImmutable = MFI.isImmutableObjectIndex(Idx); + YamlObject.IsAliased = MFI.isAliasedObjectIndex(Idx); YMF.FixedStackObjects.push_back(YamlObject); - StackObjectOperandMapping.insert( - std::make_pair(I, FrameIndexOperand::createFixed(ID))); + StackObjectOperandMapping.insert(std::make_pair( + Idx, + FrameIndexOperand::createFixed(ID, YMF.FixedStackObjects.size() - 1))); } // Process ordinary stack objects. + assert(YMF.StackObjects.empty() && "StackObjects is not empty!"); ID = 0; - for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I, ++ID) { - if (MFI.isDeadObjectIndex(I)) + for (int Idx = 0, E = MFI.getObjectIndexEnd(); Idx < E; ++Idx, ++ID) { + if (MFI.isDeadObjectIndex(Idx)) continue; yaml::MachineStackObject YamlObject; YamlObject.ID = ID; - if (const auto *Alloca = MFI.getObjectAllocation(I)) + if (const auto *Alloca = MFI.getObjectAllocation(Idx)) YamlObject.Name.Value = std::string( Alloca->hasName() ? Alloca->getName() : ""); - YamlObject.Type = MFI.isSpillSlotObjectIndex(I) + YamlObject.Type = MFI.isSpillSlotObjectIndex(Idx) ? yaml::MachineStackObject::SpillSlot - : MFI.isVariableSizedObjectIndex(I) + : MFI.isVariableSizedObjectIndex(Idx) ? yaml::MachineStackObject::VariableSized : yaml::MachineStackObject::DefaultType; - YamlObject.Offset = MFI.getObjectOffset(I); - YamlObject.Size = MFI.getObjectSize(I); - YamlObject.Alignment = MFI.getObjectAlign(I); - YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I); + YamlObject.Offset = MFI.getObjectOffset(Idx); + YamlObject.Size = MFI.getObjectSize(Idx); + YamlObject.Alignment = MFI.getObjectAlign(Idx); + YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(Idx); YMF.StackObjects.push_back(YamlObject); StackObjectOperandMapping.insert(std::make_pair( - I, FrameIndexOperand::create(YamlObject.Name.Value, ID))); + Idx, FrameIndexOperand::create(YamlObject.Name.Value, ID, + YMF.StackObjects.size() - 1))); } for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { @@ -427,13 +433,13 @@ "Invalid stack object index"); const FrameIndexOperand &StackObject = StackObjectInfo->second; if (StackObject.IsFixed) { - YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; - YMF.FixedStackObjects[StackObject.ID].CalleeSavedRestored = - CSInfo.isRestored(); + YMF.FixedStackObjects[StackObject.Idx].CalleeSavedRegister = Reg; + YMF.FixedStackObjects[StackObject.Idx].CalleeSavedRestored = + CSInfo.isRestored(); } else { - YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; - YMF.StackObjects[StackObject.ID].CalleeSavedRestored = - CSInfo.isRestored(); + YMF.StackObjects[StackObject.Idx].CalleeSavedRegister = Reg; + YMF.StackObjects[StackObject.Idx].CalleeSavedRestored = + CSInfo.isRestored(); } } } @@ -444,7 +450,7 @@ "Invalid stack object index"); const FrameIndexOperand &StackObject = StackObjectInfo->second; assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); - YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; + YMF.StackObjects[StackObject.Idx].LocalOffset = LocalObject.second; } // Print the stack object references in the frame information class after @@ -463,10 +469,10 @@ "Invalid stack object index"); const FrameIndexOperand &StackObject = StackObjectInfo->second; if (StackObject.IsFixed) { - auto &Object = YMF.FixedStackObjects[StackObject.ID]; + auto &Object = YMF.FixedStackObjects[StackObject.Idx]; printStackObjectDbgInfo(DebugVar, Object, MST); } else { - auto &Object = YMF.StackObjects[StackObject.ID]; + auto &Object = YMF.StackObjects[StackObject.Idx]; printStackObjectDbgInfo(DebugVar, Object, MST); } } diff --git a/llvm/test/CodeGen/MIR/AMDGPU/stack-id-assert.mir b/llvm/test/CodeGen/MIR/AMDGPU/stack-id-assert.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/stack-id-assert.mir @@ -0,0 +1,230 @@ +# This test used to crash MIRPrinter::convertStackObjects(). + +# RUN: llc -run-pass=si-lower-sgpr-spills,prologepilog -verify-machineinstrs -o - %s | FileCheck %s + +# CHECK-LABEL: name: foo +# CHECK: maxCallFrameSize: 0 +# CHECK-LABEL: name: bar +# CHECK: adjustsStack: true + + +--- | + target triple = "amdgcn--" + + define void @foo() { + ret void + } + + define void @bar() { + ret void + } + +... +--- +name: foo +alignment: 1 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$sgpr30_sgpr31', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +constants: [] +machineFunctionInfo: + explicitKernArgSize: 0 + maxKernArgAlign: 1 + ldsSize: 0 + dynLDSAlign: 1 + isEntryFunction: false + noSignedZerosFPMath: false + memoryBound: false + waveLimiter: false + hasSpilledSGPRs: false + hasSpilledVGPRs: false + scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3' + frameOffsetReg: '$sgpr33' + stackPtrOffsetReg: '$sgpr32' + argumentInfo: + privateSegmentBuffer: { reg: '$sgpr0_sgpr1_sgpr2_sgpr3' } + mode: + ieee: true + dx10-clamp: true + fp32-input-denormals: true + fp32-output-denormals: true + fp64-fp16-input-denormals: true + fp64-fp16-output-denormals: true + highBitsOf32BitAddress: 0 +body: | + bb.0: + successors: %bb.3(0x40000000), %bb.1(0x40000000) + liveins: $sgpr30_sgpr31 + + S_CBRANCH_SCC1 %bb.3, implicit undef $scc + S_BRANCH %bb.1 + + bb.1: + successors: %bb.2(0x80000000) + liveins: $sgpr30_sgpr31 + + renamable $vcc = S_AND_B64 $exec, 0, implicit-def dead $scc + + bb.2: + successors: %bb.4(0x04000000), %bb.2(0x7c000000) + liveins: $vcc, $sgpr30_sgpr31 + + S_CBRANCH_VCCNZ %bb.4, implicit $vcc + S_BRANCH %bb.2 + + bb.3: + liveins: $sgpr30_sgpr31 + + S_SETPC_B64_return killed renamable $sgpr30_sgpr31 + + bb.4: + liveins: $sgpr30_sgpr31 + + S_SETPC_B64_return killed renamable $sgpr30_sgpr31 + +... +--- +name: bar +alignment: 1 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$vgpr0', virtual-reg: '' } + - { reg: '$vgpr1', virtual-reg: '' } + - { reg: '$vgpr2', virtual-reg: '' } + - { reg: '$sgpr30_sgpr31', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: true + stackProtector: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: 0, size: 8, alignment: 4, + stack-id: sgpr-spill, callee-saved-register: '', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: [] +constants: [] +machineFunctionInfo: + explicitKernArgSize: 0 + maxKernArgAlign: 1 + ldsSize: 0 + dynLDSAlign: 1 + isEntryFunction: false + noSignedZerosFPMath: false + memoryBound: false + waveLimiter: false + hasSpilledSGPRs: true + hasSpilledVGPRs: false + scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3' + frameOffsetReg: '$sgpr33' + stackPtrOffsetReg: '$sgpr32' + argumentInfo: + privateSegmentBuffer: { reg: '$sgpr0_sgpr1_sgpr2_sgpr3' } + mode: + ieee: true + dx10-clamp: true + fp32-input-denormals: true + fp32-output-denormals: true + fp64-fp16-input-denormals: true + fp64-fp16-output-denormals: true + highBitsOf32BitAddress: 0 +body: | + bb.0: + successors: %bb.3(0x40000000), %bb.1(0x40000000) + liveins: $vgpr0, $vgpr1, $vgpr2, $sgpr30_sgpr31 + + renamable $vgpr41 = COPY $vgpr2, implicit $exec + renamable $vgpr40 = COPY $vgpr1, implicit $exec + renamable $vcc = V_CMP_NE_U32_e64 42, killed $vgpr0, implicit $exec + $sgpr4_sgpr5 = S_AND_SAVEEXEC_B64 $vcc, implicit-def $exec, implicit-def $scc, implicit $exec + renamable $sgpr34_sgpr35 = S_XOR_B64 $exec, killed renamable $sgpr4_sgpr5, implicit-def dead $scc + S_CBRANCH_EXECZ %bb.1, implicit $exec + S_BRANCH %bb.3 + + bb.1: + successors: %bb.2(0x40000000), %bb.4(0x40000000) + liveins: $sgpr30_sgpr31, $sgpr34_sgpr35, $vgpr40_vgpr41:0x000000000000000F + + renamable $sgpr4_sgpr5 = S_OR_SAVEEXEC_B64 killed renamable $sgpr34_sgpr35, implicit-def $exec, implicit-def $scc, implicit $exec + $exec = S_XOR_B64 $exec, renamable $sgpr4_sgpr5, implicit-def $scc + S_CBRANCH_EXECZ %bb.4, implicit $exec + S_BRANCH %bb.2 + + bb.2: + successors: %bb.4(0x80000000) + liveins: $sgpr4_sgpr5, $sgpr30_sgpr31, $vgpr40_vgpr41:0x000000000000000F + + renamable $vgpr0 = V_MOV_B32_e32 1109917696, implicit $exec + FLAT_STORE_DWORD renamable $vgpr40_vgpr41, killed renamable $vgpr0, 0, 0, 0, 0, implicit $exec, implicit $flat_scr + S_BRANCH %bb.4 + + bb.3: + successors: %bb.1(0x80000000) + liveins: $sgpr30_sgpr31, $sgpr34_sgpr35, $vgpr40_vgpr41:0x000000000000000F + + ADJCALLSTACKUP 0, 0, implicit-def dead $scc, implicit-def $sgpr32, implicit $sgpr32 + renamable $sgpr4_sgpr5 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @foo + 4, target-flags(amdgpu-gotprel32-hi) @foo + 12, implicit-def dead $scc + renamable $sgpr4_sgpr5 = S_LOAD_DWORDX2_IMM killed renamable $sgpr4_sgpr5, 0, 0, 0 :: (dereferenceable invariant load 8 from got, addrspace 4) + SI_SPILL_S64_SAVE killed renamable $sgpr30_sgpr31, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32 + dead $sgpr30_sgpr31 = SI_CALL killed renamable $sgpr4_sgpr5, @foo, csr_amdgpu_highregs, implicit $sgpr0_sgpr1_sgpr2_sgpr3 + renamable $sgpr30_sgpr31 = SI_SPILL_S64_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32 + ADJCALLSTACKDOWN 0, 0, implicit-def dead $scc, implicit-def $sgpr32, implicit $sgpr32 + S_BRANCH %bb.1 + + bb.4: + liveins: $sgpr4_sgpr5, $sgpr30_sgpr31 + + $exec = S_OR_B64 $exec, killed renamable $sgpr4_sgpr5, implicit-def $scc + S_SETPC_B64_return killed renamable $sgpr30_sgpr31 + +...