[LLVMdev] llvm.dbg.declare first arg requirement? (strictly alloca or bitcast+ of alloca okay?)

Adrian Prantl aprantl at apple.com
Tue Jun 9 16:40:59 PDT 2015


> On Jun 9, 2015, at 3:23 PM, Jan Voung <jvoung at chromium.org> wrote:
> 
> Hi,
> 
> The documentation for llvm.dbg.declare says: "This intrinsic provides information about a local element (e.g., variable). The first argument is metadata holding the alloca for the variable. The second argument is a local variable containing a description of the variable."
> 
> However, I've found that sometimes instcombine can make the first argument not literally be an alloca for the variable. It can be a bitcast. Is there meant to be an exception for bitcasts (can be multiple layers of casts), or am I reading the documentation too strictly?
> 
> 
> Example:
> 
> opt -instcombine smaller2.ll -S -o - 2>&1 | grep "llvm.dbg.declare\|tmpcast"                                                                                                        (git)-[master] 
> declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>   %tmpcast = bitcast i64* %png_signature to [8 x i8]*, !dbg !13
>   call void @llvm.dbg.declare(metadata [8 x i8]* %tmpcast, metadata !14, metadata !16), !dbg !17
>   %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %tmpcast, i32 0, i32 %start, !dbg !18
> 
> ===== Original smaller2.ll =====
> ; ModuleID = 'smaller2.ll'
> target datalayout = "e-p:32:32-i64:64-n32"
> target triple = "le32-unknown-nacl"
> 
> @png_sig_cmp.png_signature = external hidden unnamed_addr constant [8 x i8], align 1
> 
> ; Function Attrs: nounwind
> declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
> 
> declare i32 @memcmp(i8*, i8*, i32)
> 
> ; Function Attrs: nounwind readnone
> declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
> 
> define hidden i32 @png_sig_cmp(i32 %start, i32 %x, i8* %ptr) {
> entry:
>   %png_signature = alloca [8 x i8], align 1
>   call void @llvm.dbg.declare(metadata [8 x i8]* %png_signature, metadata !13, metadata !15), !dbg !16
>   %0 = bitcast [8 x i8]* %png_signature to i8*, !dbg !16
>   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @png_sig_cmp.png_signature, i32 0, i32 0), i32 8, i32 1, i1 false), !dbg !17
>   %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %png_signature, i32 0, i32 %start, !dbg !18
>   %call = call i32 @memcmp(i8* %ptr, i8* %arrayidx10, i32 %x), !dbg !19
>   ret i32 %call
> }
> 
> attributes #0 = { nounwind }
> attributes #1 = { nounwind readnone }
> 
> !llvm.ident = !{!0}
> !llvm.dbg.cu <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.dbg.cu&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=VkMIiPta_HGyqWE41Q3EB2OAu0qYCbQ882YsXHwRcDg&s=GrgD4B7jP_9w96c9ORVMk15iPnUi9R542aiCwyy8b2Q&e=> = !{!1}
> !llvm.module.flags = !{!11, !12}
> 
> !0 = !{!"clang version 3.7.0"}
> !1 = !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 3.7.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !3, retainedTypes: !3, subprograms: !4, globals: !3, imports: !3)
> !2 = !DIFile(filename: "foo.c", directory: "/s/llvm/cmakebuild")
> !3 = !{}
> !4 = !{!5}
> !5 = !DISubprogram(name: "png_sig_cmp", scope: !2, file: !2, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, function: i32 (i32, i32, i8*)* @png_sig_cmp, variables: !3)
> !6 = !DISubroutineType(types: !7)
> !7 = !{!8, !8, !8, !9}
> !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
> !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32)
> !10 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
> !11 = !{i32 2, !"Dwarf Version", i32 4}
> !12 = !{i32 2, !"Debug Info Version", i32 3}
> !13 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "png_signature", scope: !5, file: !2, line: 2, type: !14)
> !14 = !DIBasicType(name: "long long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned)
> !15 = !DIExpression()
> !16 = !DILocation(line: 2, column: 22, scope: !5)
> !17 = !DILocation(line: 3, column: 26, scope: !5)
> !18 = !DILocation(line: 4, column: 30, scope: !5)
> !19 = !DILocation(line: 5, column: 28, scope: !5)
> 
> =====
> In summary, I'm wondering if the argument should strictly be an alloca. If that's the case then instcombine's PromoteCastOfAllocation's use of RAUW should be aware of llvm.dbg.declare (http://llvm.org/docs/doxygen/html/InstCombineCasts_8cpp_source.html#l00148 <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_docs_doxygen_html_InstCombineCasts-5F8cpp-5Fsource.html-23l00148&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=VkMIiPta_HGyqWE41Q3EB2OAu0qYCbQ882YsXHwRcDg&s=sIRHYFce7Q7Dal_51_RNeQDKtdOqjzBYe2Vb29p2eGQ&e=>). Not sure if there are other transform passes that need to be aware too.
> 
> Or should I read the docs more loosely (or should the docs be clarified)?

To give an intentionally vague explanation of dbg.declare’s ill-defined semantics: the first argument needs to be a location that is live throughout the entire scope of the variable and is expected to translate into a stack slot in the backend. In practice, FunctionLoweringInfo expects either an alloca or a bitcast and silently drops everything else.
It would be a good idea to update the documentation to include bitcasts with a caveat that the bitcast should really be a bitcast of an alloca.

thanks,
adrian

> 
> Thanks,
> Jan
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150609/8b12c9bc/attachment.html>


More information about the llvm-dev mailing list