Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -1455,7 +1455,7 @@ // If SrcReg wasn't read, it may still be the case that DstReg is live-in // because SrcReg is a sub-register. - if (DstInt && !Reads && SubIdx) + if (DstInt && !Reads && SubIdx && !UseMI->isDebugValue()) Reads = DstInt->liveAt(LIS->getInstructionIndex(*UseMI)); // Replace SrcReg with DstReg in all UseMI operands. Index: test/CodeGen/AMDGPU/regcoalesce-dbg.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/regcoalesce-dbg.mir @@ -0,0 +1,143 @@ +# RUN: llc -march=amdgcn -run-pass simple-register-coalescing -o - %s +# REQUIRES: asserts +# Test that register coalescing does not allow a call to +# LIS->getInstructionIndex with a DBG_VALUE instruction, which does not have +# a slot index. +--- | + ; ModuleID = '' + source_filename = "" + target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" + + ; Function Attrs: nounwind readnone + declare i32 @llvm.amdgcn.workitem.id.x() #0 + + ; Function Attrs: nounwind + define void @test(i32 addrspace(1)* %out, <4 x i32> addrspace(1)* %in, i32 %val, i32 %idx) #1 { + %id = call i32 @llvm.amdgcn.workitem.id.x() + %id.ext = sext i32 %id to i64 + %gep.in = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* %in, i64 %id.ext + %gep.out = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %id.ext + %vec = load <4 x i32>, <4 x i32> addrspace(1)* %gep.in + tail call void @llvm.dbg.value(metadata <4 x i32> %vec, i64 0, metadata !4, metadata !11), !dbg !12 + %insert = insertelement <4 x i32> %vec, i32 %val, i32 %idx + %extract = extractelement <4 x i32> %insert, i32 %idx + store i32 %extract, i32 addrspace(1)* %gep.out + ret void + } + + ; Function Attrs: nounwind readnone + declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0 + + declare { i1, i64 } @llvm.amdgcn.if(i1) + + declare { i1, i64 } @llvm.amdgcn.else(i64) + + ; Function Attrs: readnone + declare i64 @llvm.amdgcn.break(i64) #2 + + ; Function Attrs: readnone + declare i64 @llvm.amdgcn.if.break(i1, i64) #2 + + ; Function Attrs: readnone + declare i64 @llvm.amdgcn.else.break(i64, i64) #2 + + declare i1 @llvm.amdgcn.loop(i64) + + declare void @llvm.amdgcn.end.cf(i64) + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #1 + + attributes #0 = { nounwind readnone } + attributes #1 = { nounwind } + attributes #2 = { readnone } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!3} + + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2) + !1 = !DIFile(filename: "source.c", directory: "/tmp") + !2 = !{} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !DILocalVariable(name: "a", scope: !5, file: !1, line: 126, type: !9) + !5 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !8) + !6 = !DISubroutineType(types: !7) + !7 = !{null} + !8 = !{!4} + !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 32) + !10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) + !11 = !DIExpression() + !12 = !DILocation(line: 126, column: 9, scope: !5) + +... +--- +name: test +alignment: 0 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: sgpr_64 } + - { id: 1, class: sreg_32_xm0 } + - { id: 2, class: sgpr_32 } + - { id: 3, class: vgpr_32 } + - { id: 4, class: sreg_64_xexec } + - { id: 5, class: sreg_32_xm0_xexec } + - { id: 6, class: sreg_32 } + - { id: 7, class: sreg_32 } + - { id: 8, class: sreg_32_xm0 } + - { id: 9, class: sreg_64 } + - { id: 10, class: sreg_32_xm0 } + - { id: 11, class: sreg_32_xm0 } + - { id: 12, class: sgpr_64 } + - { id: 13, class: sgpr_128 } + - { id: 14, class: sreg_32_xm0 } + - { id: 15, class: sreg_64 } + - { id: 16, class: vgpr_32 } + - { id: 17, class: vreg_64 } + - { id: 18, class: vgpr_32 } + - { id: 19, class: vreg_64 } + - { id: 20, class: vreg_64 } +liveins: + - { reg: '%sgpr0_sgpr1', virtual-reg: '%0' } + - { reg: '%vgpr0', virtual-reg: '%3' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0 (%ir-block.0): + liveins: %sgpr0_sgpr1, %vgpr0 + + %3 = COPY killed %vgpr0 + %0 = COPY killed %sgpr0_sgpr1 + %4 = S_LOAD_DWORDX2_IMM %0, 9, 0 :: (non-temporal dereferenceable invariant load 8 from `i64 addrspace(2)* undef`) + %5 = S_LOAD_DWORD_IMM killed %0, 13, 0 :: (non-temporal dereferenceable invariant load 4 from `i32 addrspace(2)* undef`) + %18 = V_ASHRREV_I32_e32 31, %3, implicit %exec + undef %19.sub0 = COPY killed %3 + %19.sub1 = COPY killed %18 + %10 = S_MOV_B32 61440 + %11 = S_MOV_B32 0 + DBG_VALUE debug-use %11, debug-use _, !4, !11, debug-location !12 + undef %12.sub0 = COPY killed %11 + %12.sub1 = COPY killed %10 + undef %13.sub0_sub1 = COPY killed %4 + %13.sub2_sub3 = COPY killed %12 + %20 = V_LSHL_B64 killed %19, 2, implicit %exec + %16 = COPY killed %5 + BUFFER_STORE_DWORD_ADDR64 killed %16, killed %20, killed %13, 0, 0, 0, 0, 0, implicit %exec :: (store 4 into %ir.gep.out) + S_ENDPGM + +...