llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.19k stars 12.04k forks source link

Invalid llvm.dbg.declare intrinsic call after instruction combine pass #56807

Open tvivies-amd opened 2 years ago

tvivies-amd commented 2 years ago

For the following IR after running instruction combine pass the operand of the dbg.declare intrinsic call is undef which make the call invalid. https://godbolt.org/z/qxn97vWrd

%struct.Pixel = type { i8, i8, i8 }

declare void @foo(i8* %pixels)

declare void @llvm.dbg.declare(metadata, metadata, metadata)

define dso_local void @toplevel() {
entry:
  %pixels = alloca [500 x %struct.Pixel]
  call void @llvm.dbg.declare(metadata [500 x %struct.Pixel]* %pixels, metadata !11, metadata !DIExpression()), !dbg !12
  %arraydecay = bitcast [500 x %struct.Pixel]* %pixels to i8*
  call void @foo(i8* %arraydecay)
  ret void
}

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.1.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "test.cpp", directory: "")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 11.1.0"}
!7 = distinct !DISubprogram(name: "square", linkageName: "_Z6squarei", scope: !1, file: !1, line: 9, type: !8, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !DILocalVariable(name: "num", arg: 1, scope: !7, file: !1, line: 9, type: !10)
!12 = !DILocation(line: 9, column: 16, scope: !7)
!13 = !DILocalVariable(name: "Pixel", scope: !7, file: !1, line: 10, type: !14)
!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 16000, elements: !15)
!15 = !{!16}
!16 = !DISubrange(count: 500)
!17 = !DILocation(line: 10, column: 9, scope: !7)
!18 = !DILocation(line: 12, column: 5, scope: !7)
llvmbot commented 2 years ago

@llvm/issue-subscribers-debuginfo

nikolaos-amd commented 2 years ago

I wonder if it is possible to save the debug info for the alloca Inst before it *is being eliminated and also have metadata about the %pixels1 alloca return value, as in: https://alive2.llvm.org/ce/z/_n-rjA

Note lines 17-18 in the tgt function. The question is what kind of resulting IR would we want after rewriting the uses of the operand of the dying instruction. Like line 17 or like line 18 (which is more about the GEP after the bitcast replacement?)

jmorse commented 2 years ago

This is a good find, thanks for reporting the dropped variable location -- I'm not familiar with the transformation being performed, but would have expected RAUW to just swap one alloca for another, so this is a mild surprise,

Note lines 17-18 in the tgt function. The question is what kind of resulting IR would we want after rewriting the uses of the operand of the dying instruction.

I'd suggest line 17 is preferred -- there are various portions of code that try to match dbg.declares with allocas, it's easier if there's nothing in the way, and dbg.declare aims only to identify the storage for a variable, not how it's used.

nikolaos-amd commented 2 years ago

Thank you. We have corrected this so we will match the dbg.declare with the alloca instead and there is no new dbg.declare on the GEP.

; CHECK-LABEL: define dso_local i8* @toplevel(
; CHECK:  entry:
; CHECK-NEXT:    %pixels1 = alloca [1500 x i8], align 8
; CHECK-NEXT:    call void @llvm.dbg.declare(metadata [1500 x i8]* %pixels1, metadata !7, metadata !DIExpression()), !dbg !12
; CHECK-NEXT:    %pixels1.sub = getelementptr inbounds [1500 x i8], [1500 x i8]* %pixels1, i64 0, i64 0
; CHECK-NEXT:    ret i8* %pixels1.sub
define dso_local i8* @toplevel() {
entry:
  %pixels = alloca [500 x %struct.Pixel]
  call void @llvm.dbg.declare(metadata [500 x %struct.Pixel]* %pixels, metadata !11, metadata !DIExpression()), !dbg !12
  %arraydecay = bitcast [500 x %struct.Pixel]* %pixels to i8*
  ret i8* %arraydecay
}

as shown in the resulting IR after -instcombine is in the CHECK lines.

jmorse commented 2 years ago

Sweet, please do add me on the relevant review!