Jan Voung
2015-Jun-09 22:23 UTC
[LLVMdev] llvm.dbg.declare first arg requirement? (strictly alloca or bitcast+ of alloca okay?)
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 = !{!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). 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)? Thanks, Jan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150609/53050fad/attachment.html>
Adrian Prantl
2015-Jun-09 23:40 UTC
[LLVMdev] llvm.dbg.declare first arg requirement? (strictly alloca or bitcast+ of alloca okay?)
> 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>