Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tvivies-amd opened this issue Jul 29, 2022 · 5 comments
Open

Comments

@tvivies-amd
Copy link

tvivies-amd commented Jul 29, 2022

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
Copy link
Collaborator

llvmbot commented Aug 19, 2022

@llvm/issue-subscribers-debuginfo

@nikolaos-amd
Copy link

nikolaos-amd commented Aug 22, 2022

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
Copy link
Member

jmorse commented Aug 26, 2022

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
Copy link

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
Copy link
Member

jmorse commented Aug 26, 2022

Sweet, please do add me on the relevant review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants