diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -14,13 +14,14 @@ #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H +#include "BTF.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringMap.h" #include "llvm/CodeGen/DebugHandlerBase.h" #include #include #include #include -#include "BTF.h" namespace llvm { @@ -48,6 +49,7 @@ virtual ~BTFTypeBase() = default; void setId(uint32_t Id) { this->Id = Id; } uint32_t getId() { return Id; } + uint32_t getKind() { return Kind; } uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } /// Get the size of this BTF type entry. virtual uint32_t getSize() { return BTF::CommonTypeSize; } @@ -240,6 +242,7 @@ BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag); BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag); void completeType(BTFDebug &BDebug) override; + uint32_t getNextTypeId(); }; /// String table. @@ -285,6 +288,27 @@ uint32_t RelocKind; ///< What to patch the instruction }; +struct BTFTypeDedupKey { + const dwarf::Tag Kind; + const StringRef Name; + const uint64_t BasicTypeRepr; + + BTFTypeDedupKey(dwarf::Tag Kind, StringRef Name, uint64_t BasicTypeRepr) + : Kind(Kind), Name(Name), BasicTypeRepr(BasicTypeRepr) {} + + bool operator==(const BTFTypeDedupKey &Other) const { + return Kind == Other.Kind && Name == Other.Name && + BasicTypeRepr == Other.BasicTypeRepr; + } + + struct Hash { + size_t operator()(BTFTypeDedupKey const &Key) const { + return hash_combine(hash_value(Key.Kind), hash_value(Key.Name), + hash_value(Key.BasicTypeRepr)); + } + }; +}; + /// Collect and emit BTF information. class BTFDebug : public DebugHandlerBase { MCStreamer &OS; @@ -296,6 +320,8 @@ BTFStringTable StringTable; std::vector> TypeEntries; std::unordered_map DIToIdMap; + std::unordered_map + DIDedupMap; std::map> FuncInfoTable; std::map> LineInfoTable; std::map> FieldRelocTable; @@ -311,11 +337,14 @@ /// Add types to TypeEntries. /// @{ /// Add types to TypeEntries and DIToIdMap. - uint32_t addType(std::unique_ptr TypeEntry, const DIType *Ty); + uint32_t addType(std::unique_ptr TypeEntry, const DIType *Ty, + uint32_t *RealId = nullptr); /// Add types to TypeEntries only and return type id. uint32_t addType(std::unique_ptr TypeEntry); /// @} + std::optional lookupType(const DIType *Ty); + /// IR type visiting functions. /// @{ void visitTypeEntry(const DIType *Ty); @@ -365,7 +394,7 @@ /// the base type of DTy. Return the type id of the first BTF type_tag /// in the chain. If no type_tag's are generated, a negative value /// is returned. - int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId); + uint32_t genBTFTypeTags(const DIType *Ty, uint32_t BaseId); /// Generate one field relocation record. void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId, @@ -387,6 +416,8 @@ /// Emit the .BTF.ext section. void emitBTFExtSection(); + uint32_t skipBTFTypeTags(uint32_t Id); + protected: /// Gather pre-function debug information. void beginFunctionImpl(const MachineFunction *MF) override; diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -489,6 +489,8 @@ } } +uint32_t BTFTypeTypeTag::getNextTypeId() { return BTFType.Type; } + uint32_t BTFStringTable::addString(StringRef S) { // Check whether the string already exists. for (auto &OffsetM : OffsetToIdMap) { @@ -510,13 +512,89 @@ addString("\0"); } +static DINodeArray lookupAnnotations(const DIType *Ty) { + DINodeArray Annots = {}; + if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + return Annots; +} + +static void collectBTFTypeTags(const DIType *Ty, + SmallVectorImpl &Tags) { + DINodeArray Annots = lookupAnnotations(Ty); + if (!Annots) + return; + + for (const Metadata *Annotations : Annots->operands()) { + const MDNode *MD = cast(Annotations); + if (MD->getNumOperands() != 2) + continue; + const MDString *Name = dyn_cast(MD->getOperand(0)); + if (!Name) + continue; + if (!Name->getString().equals("btf:type_tag")) + continue; + // For type with "int __tag1 __tag2 *p", the Tags will have + // content: [__tag1, __tag2]. + Tags.push_back(cast(MD->getOperand(1))); + } +} + +/// Generate btf_type_tag chains. +uint32_t BTFDebug::genBTFTypeTags(const DIType *Ty, uint32_t BaseId) { + SmallVector MDStrs; + collectBTFTypeTags(Ty, MDStrs); + // With MDStrs [__tag1, __tag2], the output type chain looks like + // PTR -> __tag2 -> __tag1 -> BaseType + // In the below, we construct BTF types with the order of __tag1, __tag2 + // and PTR. + for (unsigned I = 0; I < MDStrs.size(); I++) { + const MDString *Value = MDStrs[I]; + auto TagEntry = + std::make_unique(BaseId, Value->getString()); + BaseId = addType(std::move(TagEntry)); + } + return BaseId; +} + +static std::optional makeDedupKey(const DIType *Ty) { + if (Ty->getName().empty()) + return std::nullopt; + + if (auto *BTy = dyn_cast(Ty)) { + uint32_t Repr = BTy->getEncoding() << 24 | BTy->getOffsetInBits() << 16 | + BTy->getSizeInBits(); + return std::optional(BTFTypeDedupKey(Ty->getTag(), Ty->getName(), Repr)); + } + + switch (Ty->getTag()) { + case dwarf::Tag::DW_TAG_enumeration_type: + case dwarf::Tag::DW_TAG_structure_type: + case dwarf::Tag::DW_TAG_union_type: + case dwarf::Tag::DW_TAG_typedef: + return std::optional(BTFTypeDedupKey(Ty->getTag(), Ty->getName(), 0)); + default: + return std::nullopt; + } +} + uint32_t BTFDebug::addType(std::unique_ptr TypeEntry, - const DIType *Ty) { - TypeEntry->setId(TypeEntries.size() + 1); - uint32_t Id = TypeEntry->getId(); - DIToIdMap[Ty] = Id; - TypeEntries.push_back(std::move(TypeEntry)); - return Id; + const DIType *Ty, uint32_t *RealId) { + uint32_t Id = TypeEntry ? addType(std::move(TypeEntry)) : 0; + auto Key = makeDedupKey(Ty); + if (Key.has_value()) + DIDedupMap[*Key] = Id; + uint32_t TagId = genBTFTypeTags(Ty, Id); + DIToIdMap[Ty] = TagId; + if (RealId) + *RealId = Id; + return TagId; } uint32_t BTFDebug::addType(std::unique_ptr TypeEntry) { @@ -526,7 +604,30 @@ return Id; } +std::optional BTFDebug::lookupType(const DIType *Ty) { + if (DIToIdMap.find(Ty) != DIToIdMap.end()) + return std::optional(DIToIdMap[Ty]); + + auto Key = makeDedupKey(Ty); + if (!Key.has_value() || (DIDedupMap.find(*Key) == DIDedupMap.end())) + return std::nullopt; + + SmallVector MDStrs; + collectBTFTypeTags(Ty, MDStrs); + auto TagId = genBTFTypeTags(Ty, DIDedupMap[*Key]); + DIToIdMap[Ty] = TagId; + return TagId; +} + void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) { + // Such "void" entries might arise from use btf_type_tag, e.g.: + // void __attribute__((btf_type_tag("foo"))) *p; + if (BTy->getTag() == dwarf::DW_TAG_unspecified_type && + BTy->getName() == "void") { + TypeId = addType(nullptr, BTy); + return; + } + // Only int and binary floating point types are supported in BTF. uint32_t Encoding = BTy->getEncoding(); std::unique_ptr TypeEntry; @@ -616,46 +717,6 @@ return FuncId; } -/// Generate btf_type_tag chains. -int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) { - SmallVector MDStrs; - DINodeArray Annots = DTy->getAnnotations(); - if (Annots) { - // For type with "int __tag1 __tag2 *p", the MDStrs will have - // content: [__tag1, __tag2]. - for (const Metadata *Annotations : Annots->operands()) { - const MDNode *MD = cast(Annotations); - const MDString *Name = cast(MD->getOperand(0)); - if (!Name->getString().equals("btf_type_tag")) - continue; - MDStrs.push_back(cast(MD->getOperand(1))); - } - } - - if (MDStrs.size() == 0) - return -1; - - // With MDStrs [__tag1, __tag2], the output type chain looks like - // PTR -> __tag2 -> __tag1 -> BaseType - // In the below, we construct BTF types with the order of __tag1, __tag2 - // and PTR. - unsigned TmpTypeId; - std::unique_ptr TypeEntry; - if (BaseTypeId >= 0) - TypeEntry = - std::make_unique(BaseTypeId, MDStrs[0]->getString()); - else - TypeEntry = std::make_unique(DTy, MDStrs[0]->getString()); - TmpTypeId = addType(std::move(TypeEntry)); - - for (unsigned I = 1; I < MDStrs.size(); I++) { - const MDString *Value = MDStrs[I]; - TypeEntry = std::make_unique(TmpTypeId, Value->getString()); - TmpTypeId = addType(std::move(TypeEntry)); - } - return TmpTypeId; -} - /// Handle structure/union types. void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, uint32_t &TypeId) { @@ -677,17 +738,18 @@ auto TypeEntry = std::make_unique(CTy, IsStruct, HasBitField, VLen); StructTypes.push_back(TypeEntry.get()); - TypeId = addType(std::move(TypeEntry), CTy); + uint32_t StructId; + TypeId = addType(std::move(TypeEntry), CTy, &StructId); // Check struct/union annotations - processDeclAnnotations(CTy->getAnnotations(), TypeId, -1); + processDeclAnnotations(CTy->getAnnotations(), StructId, -1); // Visit all struct members. int FieldNo = 0; for (const auto *Element : Elements) { const auto Elem = cast(Element); visitTypeEntry(Elem); - processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo); + processDeclAnnotations(Elem->getAnnotations(), StructId, FieldNo); FieldNo++; } } @@ -814,19 +876,9 @@ } } - if (Tag == dwarf::DW_TAG_pointer_type) { - int TmpTypeId = genBTFTypeTags(DTy, -1); - if (TmpTypeId >= 0) { - auto TypeDEntry = - std::make_unique(TmpTypeId, Tag, DTy->getName()); - TypeId = addType(std::move(TypeDEntry), DTy); - } else { - auto TypeEntry = std::make_unique(DTy, Tag, false); - TypeId = addType(std::move(TypeEntry), DTy); - } - } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type || - Tag == dwarf::DW_TAG_volatile_type || - Tag == dwarf::DW_TAG_restrict_type) { + if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef || + Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || + Tag == dwarf::DW_TAG_restrict_type) { auto TypeEntry = std::make_unique(DTy, Tag, false); TypeId = addType(std::move(TypeEntry), DTy); if (Tag == dwarf::DW_TAG_typedef) @@ -846,8 +898,13 @@ void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, bool SeenPointer) { - if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) { + if (!Ty) { TypeId = DIToIdMap[Ty]; + return; + } + + if (auto OptTypeId = lookupType(Ty)) { + TypeId = *OptTypeId; // To handle the case like the following: // struct t; @@ -878,14 +935,14 @@ // We will traverse const/ptr/volatile which already have corresponding // BTF types and generate type for 'struct' which might be in Fixup // state. - if (Ty && (!CheckPointer || !SeenPointer)) { + if (!CheckPointer || !SeenPointer) { if (const auto *DTy = dyn_cast(Ty)) { while (DTy) { const DIType *BaseTy = DTy->getBaseType(); if (!BaseTy) break; - if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) { + if (lookupType(BaseTy)) { DTy = dyn_cast(BaseTy); } else { uint32_t TmpTypeId; @@ -1224,6 +1281,22 @@ SecNameOff = 0; } +uint32_t BTFDebug::skipBTFTypeTags(uint32_t Id) { + for (;;) { + if (Id == 0) + break; + + BTFTypeBase *Ty = TypeEntries[Id - 1].get(); + if (Ty->getKind() != BTF::BTF_KIND_TYPE_TAG) + break; + + auto *TagTy = static_cast(Ty); + Id = TagTy->getNextTypeId(); + } + + return Id; +} + /// On-demand populate types as requested from abstract member /// accessing or preserve debuginfo type. unsigned BTFDebug::populateType(const DIType *Ty) { @@ -1231,7 +1304,10 @@ visitTypeEntry(Ty, Id, false, false); for (const auto &TypeEntry : TypeEntries) TypeEntry->completeType(*this); - return Id; + + // Skip type tags, libbpf expects each relocation entry to point to + // struct/union/enum. + return skipBTFTypeTags(Id); } /// Generate a struct member field relocation. @@ -1424,6 +1500,9 @@ break; } + // Kernel does not handle VARs with type 'TYPE_TAG -> something' + GVTypeId = skipBTFTypeTags(GVTypeId); + // Only support the following globals: // . static variables // . non-static weak or non-weak global variables @@ -1579,27 +1658,17 @@ // Search through struct types uint32_t StructTypeId = 0; - for (const auto &StructType : StructTypes) { - if (StructType->getName() == TypeName) { - StructTypeId = StructType->getId(); - break; - } - } + if (auto OptId = lookupType(CTy)) + StructTypeId = *OptId; if (StructTypeId == 0) { auto FwdTypeEntry = std::make_unique(TypeName, IsUnion); - StructTypeId = addType(std::move(FwdTypeEntry)); + StructTypeId = addType(std::move(FwdTypeEntry), CTy); } for (auto &TypeInfo : Fixup.second) { - const DIDerivedType *DTy = TypeInfo.first; BTFTypeDerived *BDType = TypeInfo.second; - - int TmpTypeId = genBTFTypeTags(DTy, StructTypeId); - if (TmpTypeId >= 0) - BDType->setPointeeType(TmpTypeId); - else - BDType->setPointeeType(StructTypeId); + BDType->setPointeeType(StructTypeId); } } diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll @@ -0,0 +1,118 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; enum foo { FOO }; +; +; struct bar { +; enum foo __tag1 aa; +; enum foo __tag2 bb; +; enum foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !15 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !31, metadata !DIExpression()), !dbg !32 + ret void, !dbg !33 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FOO", value: 0) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 8, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 2} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!15 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !16, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !30) +!16 = !DISubroutineType(types: !17) +!17 = !{null, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, size: 96, elements: !20) +!20 = !{!21, !25, !29} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !19, file: !1, line: 7, baseType: !22, size: 32) +!22 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5, annotations: !23) +!23 = !{!24} +!24 = !{!"btf:type_tag", !"tag1"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !19, file: !1, line: 8, baseType: !26, size: 32, offset: 32) +!26 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5, annotations: !27) +!27 = !{!28} +!28 = !{!"btf:type_tag", !"tag2"} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !19, file: !1, line: 9, baseType: !3, size: 32, offset: 64) +!30 = !{} +!31 = !DILocalVariable(name: "bar", arg: 1, scope: !15, file: !1, line: 12, type: !18) +!32 = !DILocation(line: 12, column: 23, scope: !15) +!33 = !DILocation(line: 12, column: 29, scope: !15) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 14 # BTF_KIND_ENUM(id = 4) +; CHECK-NEXT: .long 100663297 # 0x6000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 22 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 27 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "FOO" # string offset=18 +; CHECK: .ascii "tag1" # string offset=22 +; CHECK: .ascii "tag2" # string offset=27 +; CHECK: .ascii "root" # string offset=32 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll @@ -0,0 +1,111 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; struct foo {}; +; +; struct bar { +; struct foo __tag1 aa; +; struct foo __tag2 bb; +; struct foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !27, metadata !DIExpression()), !dbg !28 + ret void, !dbg !29 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17) +!17 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !19) +!18 = !{} +!19 = !{!20} +!20 = !{!"btf:type_tag", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22) +!22 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf:type_tag", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26) +!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18) +!27 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!28 = !DILocation(line: 12, column: 23, scope: !10) +!29 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 14 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108864 # 0x4000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 28 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "tag2" # string offset=23 +; CHECK: .ascii "root" # string offset=28 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll @@ -0,0 +1,117 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; typedef int foo; +; +; struct bar { +; foo __tag1 aa; +; foo __tag2 bb; +; foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !28, metadata !DIExpression()), !dbg !29 + ret void, !dbg !30 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !27) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, size: 96, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17, size: 32) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18, annotations: !19) +!18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!19 = !{!20} +!20 = !{!"btf:type_tag", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22, size: 32, offset: 32) +!22 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf:type_tag", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26, size: 32, offset: 64) +!26 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18) +!27 = !{} +!28 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!29 = !DILocation(line: 12, column: 23, scope: !10) +!30 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 14 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 27 # BTF_KIND_TYPE_TAG(id = 7) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # BTF_KIND_FUNC(id = 8) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "int" # string offset=23 +; CHECK: .ascii "tag2" # string offset=27 +; CHECK: .ascii "root" # string offset=32 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll @@ -0,0 +1,111 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; union foo {}; +; +; struct bar { +; union foo __tag1 aa; +; union foo __tag2 bb; +; union foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !27, metadata !DIExpression()), !dbg !28 + ret void, !dbg !29 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17) +!17 = !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !19) +!18 = !{} +!19 = !{!20} +!20 = !{!"btf:type_tag", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22) +!22 = !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf:type_tag", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26) +!26 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18) +!27 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!28 = !DILocation(line: 12, column: 23, scope: !10) +!29 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 14 # BTF_KIND_UNION(id = 4) +; CHECK-NEXT: .long 83886080 # 0x5000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 28 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "tag2" # string offset=23 +; CHECK: .ascii "root" # string offset=28 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-field-relo.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-field-relo.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-field-relo.ll @@ -0,0 +1,134 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s +; +; Source: +; +; #define __pai __attribute__((preserve_access_index)); +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; +; struct alpha { +; int zulu; +; } __pai; +; +; struct bravo { +; struct alpha __tag1 *yankee; +; } __pai; +; +; int func(struct bravo *xray) { +; return xray->yankee->zulu; +; } +; +; Compilation command: +; +; cat test.c | clang -x c -target bpf -O2 -g -emit-llvm -S - -o - +; +; The relocation entry for zulu should point to STRUCT 'alpha', +; not TYPE_TAG 'tag1' -> STRUCT 'alpha'. + +@"llvm.alpha:0:0$0:0" = external global i64, !llvm.preserve.access.index !0 #0 +@"llvm.bravo:0:0$0:0" = external global i64, !llvm.preserve.access.index !8 #0 + +; Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none) +define dso_local i32 @func(ptr noundef readonly %xray) local_unnamed_addr #1 !dbg !22 { +entry: + call void @llvm.dbg.value(metadata ptr %xray, metadata !27, metadata !DIExpression()), !dbg !28 + %0 = load i64, ptr @"llvm.bravo:0:0$0:0", align 8 + %1 = getelementptr i8, ptr %xray, i64 %0 + %2 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 1, ptr %1) + %3 = load ptr, ptr %2, align 8, !dbg !29, !tbaa !30 + %4 = load i64, ptr @"llvm.alpha:0:0$0:0", align 8 + %5 = getelementptr i8, ptr %3, i64 %4 + %6 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %5) + %7 = load i32, ptr %6, align 4, !dbg !35, !tbaa !36 + ret i32 %7, !dbg !39 +} + +; Function Attrs: nofree nosync nounwind memory(none) +declare ptr @llvm.bpf.passthrough.p0.p0(i32, ptr) #2 + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { "btf_ama" } +attributes #1 = { nofree nosync nounwind memory(read, inaccessiblemem: none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { nofree nosync nounwind memory(none) } +attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!14} +!llvm.module.flags = !{!17, !18, !19, !20} +!llvm.ident = !{!21} + +!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "alpha", file: !1, line: 4, size: 32, elements: !2, annotations: !6) +!1 = !DIFile(filename: "", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "89810ba04b039111ea709cb54ed653bc") +!2 = !{!3} +!3 = !DIDerivedType(tag: DW_TAG_member, name: "zulu", scope: !4, file: !1, line: 5, baseType: !5, size: 32) +!4 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "alpha", file: !1, line: 4, size: 32, elements: !2) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !{!7} +!7 = !{!"btf:type_tag", !"tag1"} +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bravo", file: !1, line: 8, size: 64, elements: !9) +!9 = !{!10} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "yankee", scope: !8, file: !1, line: 9, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !0, size: 64, annotations: !12) +!12 = !{!13} +!13 = !{!"btf_type_tag", !"tag1"} +!14 = distinct !DICompileUnit(language: DW_LANG_C11, file: !15, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 034dbeecee00be5c47fc265333c6d58bb4801240)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !16, splitDebugInlining: false, nameTableKind: None) +!15 = !DIFile(filename: "-", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "89810ba04b039111ea709cb54ed653bc") +!16 = !{!0} +!17 = !{i32 7, !"Dwarf Version", i32 5} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{i32 7, !"frame-pointer", i32 2} +!21 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 034dbeecee00be5c47fc265333c6d58bb4801240)"} +!22 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 12, type: !23, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !14, retainedNodes: !26) +!23 = !DISubroutineType(types: !24) +!24 = !{!5, !25} +!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64) +!26 = !{!27} +!27 = !DILocalVariable(name: "xray", arg: 1, scope: !22, file: !1, line: 12, type: !25) +!28 = !DILocation(line: 0, scope: !22) +!29 = !DILocation(line: 13, column: 16, scope: !22) +!30 = !{!31, !32, i64 0} +!31 = !{!"bravo", !32, i64 0} +!32 = !{!"any pointer", !33, i64 0} +!33 = !{!"omnipotent char", !34, i64 0} +!34 = !{!"Simple C/C++ TBAA"} +!35 = !DILocation(line: 13, column: 24, scope: !22) +!36 = !{!37, !38, i64 0} +!37 = !{!"alpha", !38, i64 0} +!38 = !{!"int", !33, i64 0} +!39 = !DILocation(line: 13, column: 3, scope: !22) + +; CHECK: [[L1:.Ltmp[0-9]+]]: +; CHECK: r1 = *(u64 *)(r1 + 0) +; CHECK: r0 = *(u32 *)(r1 + 0) + +; CHECK: .long 1 # BTF_KIND_STRUCT(id = 2) +; CHECK: .long 66 # BTF_KIND_STRUCT(id = 7) +; CHECK: .long 77 # BTF_KIND_TYPE_TAG(id = 8) +; +; CHECK: .ascii "bravo" # string offset=1 +; CHECK: .ascii "0:0" # string offset=34 +; CHECK: .ascii "alpha" # string offset=66 + +; CHECK: .long 16 # FieldReloc +; CHECK-NEXT: .long 28 # Field reloc section string offset=28 +; CHECK-NEXT: .long 2 +; +; Step #1: xray->yankee +; CHECK-NEXT: .long [[L1]] +; CHECK-NEXT: .long 2 +; ^^^ id 2 -> STRUCT 'bravo' +; CHECK-NEXT: .long 34 +; ^^^^ relocation spec '0:0' +; CHECK-NEXT: .long 0 +; +; Step #2: yankee->zulu +; CHECK-NEXT: .long .Ltmp[[#]] +; CHECK-NEXT: .long 7 +; ^^^ id 7 -> STRUCT 'alpha' +; The gist of the test-case is to check that +; it is not id 8, corresponding to TYPE_TAG. +; CHECK-NEXT: .long 34 +; ^^^^ relocation spec '0:0' +; CHECK-NEXT: .long 0 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll @@ -18,81 +18,78 @@ ; Compilation flag: ; clang -target bpf -O2 -g -S -emit-llvm test.c -%struct.map_value = type { %struct.foo* } -%struct.foo = type opaque +%struct.map_value = type { ptr } ; Function Attrs: nounwind define dso_local void @test() local_unnamed_addr #0 !dbg !7 { entry: %v = alloca %struct.map_value, align 8 - %0 = bitcast %struct.map_value* %v to i8*, !dbg !20 - call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !20 - call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !21 - %1 = bitcast %struct.map_value* %v to i64*, !dbg !21 - store i64 0, i64* %1, align 8, !dbg !21 - call void @func(%struct.map_value* noundef nonnull %v) #4, !dbg !22 - call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 - ret void, !dbg !23 + call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %v) #4, !dbg !23 + call void @llvm.dbg.declare(metadata ptr %v, metadata !11, metadata !DIExpression()), !dbg !24 + store i64 0, ptr %v, align 8, !dbg !24 + call void @func(ptr noundef nonnull %v) #4, !dbg !25 + call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %v) #4, !dbg !26 + ret void, !dbg !26 } -; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) -; CHECK-NEXT: .long 218103808 # 0xd000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) -; CHECK-NEXT: .long 201326593 # 0xc000001 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) -; CHECK-NEXT: .long 218103809 # 0xd000001 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 62 # BTF_KIND_STRUCT(id = 5) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 72 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 76 # BTF_KIND_TYPE_TAG(id = 6) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 9 -; CHECK-NEXT: .long 81 # BTF_KIND_TYPE_TAG(id = 7) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 8) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 7 -; CHECK-NEXT: .long 86 # BTF_KIND_FWD(id = 9) -; CHECK-NEXT: .long 117440512 # 0x7000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 90 # BTF_KIND_FUNC(id = 10) -; CHECK-NEXT: .long 201326594 # 0xc000002 -; CHECK-NEXT: .long 3 +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 35 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 49 # BTF_KIND_FWD(id = 7) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 53 # BTF_KIND_TYPE_TAG(id = 8) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 58 # BTF_KIND_TYPE_TAG(id = 9) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 63 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 -; CHECK: .ascii "test" # string offset=1 -; CHECK: .ascii "map_value" # string offset=62 -; CHECK: .ascii "ptr" # string offset=72 -; CHECK: .ascii "tag2" # string offset=76 -; CHECK: .ascii "tag1" # string offset=81 -; CHECK: .ascii "foo" # string offset=86 -; CHECK: .ascii "func" # string offset=90 +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=35 +; CHECK: .ascii "ptr" # string offset=45 +; CHECK: .ascii "foo" # string offset=49 +; CHECK: .ascii "tag2" # string offset=53 +; CHECK: .ascii "tag1" # string offset=58 +; CHECK: .ascii "func" # string offset=63 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 -; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 -declare !dbg !24 dso_local void @func(%struct.map_value* noundef) local_unnamed_addr #3 +declare !dbg !27 dso_local void @func(ptr noundef) local_unnamed_addr #3 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 -attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } -attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } attributes #4 = { nounwind } @@ -100,13 +97,13 @@ !llvm.module.flags = !{!2, !3, !4, !5} !llvm.ident = !{!6} -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "7735a89e98603fee29d352a8e9db5acb") +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{i32 1, !"wchar_size", i32 4} !5 = !{i32 7, !"frame-pointer", i32 2} -!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!6 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} !7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !8, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) !8 = !DISubroutineType(types: !9) !9 = !{null} @@ -115,17 +112,21 @@ !12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 5, size: 64, elements: !13) !13 = !{!14} !14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 6, baseType: !15, size: 64) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !17) -!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20) +!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl, annotations: !17) !17 = !{!18, !19} -!18 = !{!"btf_type_tag", !"tag2"} -!19 = !{!"btf_type_tag", !"tag1"} -!20 = !DILocation(line: 11, column: 9, scope: !7) -!21 = !DILocation(line: 11, column: 26, scope: !7) -!22 = !DILocation(line: 12, column: 9, scope: !7) -!23 = !DILocation(line: 13, column: 1, scope: !7) -!24 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !28) -!25 = !DISubroutineType(types: !26) -!26 = !{null, !27} -!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) -!28 = !{} +!18 = !{!"btf:type_tag", !"tag2"} +!19 = !{!"btf:type_tag", !"tag1"} +!20 = !{!21, !22} +!21 = !{!"btf_type_tag", !"tag2"} +!22 = !{!"btf_type_tag", !"tag1"} +!23 = !DILocation(line: 11, column: 9, scope: !7) +!24 = !DILocation(line: 11, column: 26, scope: !7) +!25 = !DILocation(line: 12, column: 9, scope: !7) +!26 = !DILocation(line: 13, column: 1, scope: !7) +!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !31) +!28 = !DISubroutineType(types: !29) +!29 = !{null, !30} +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!31 = !{!32} +!32 = !DILocalVariable(arg: 1, scope: !27, file: !1, line: 8, type: !30) diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll @@ -20,95 +20,92 @@ ; Compilation flag: ; clang -target bpf -O2 -g -S -emit-llvm test.c -%struct.map_value = type { %struct.foo* } -%struct.foo = type { i32 } +%struct.map_value = type { ptr } ; Function Attrs: nounwind define dso_local void @test() local_unnamed_addr #0 !dbg !7 { entry: %v = alloca %struct.map_value, align 8 - %0 = bitcast %struct.map_value* %v to i8*, !dbg !23 - call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 - call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !24 - %1 = bitcast %struct.map_value* %v to i64*, !dbg !24 - store i64 0, i64* %1, align 8, !dbg !24 - call void @func(%struct.map_value* noundef nonnull %v, %struct.foo* noundef null) #4, !dbg !25 - call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !26 - ret void, !dbg !26 + call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %v) #4, !dbg !27 + call void @llvm.dbg.declare(metadata ptr %v, metadata !11, metadata !DIExpression()), !dbg !28 + store i64 0, ptr %v, align 8, !dbg !28 + call void @func(ptr noundef nonnull %v, ptr noundef null) #4, !dbg !29 + call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %v) #4, !dbg !30 + ret void, !dbg !30 } -; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) -; CHECK-NEXT: .long 218103808 # 0xd000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) -; CHECK-NEXT: .long 201326593 # 0xc000001 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) -; CHECK-NEXT: .long 218103810 # 0xd000002 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 7 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 63 # BTF_KIND_STRUCT(id = 5) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 73 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 12 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 77 # BTF_KIND_STRUCT(id = 8) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 81 -; CHECK-NEXT: .long 9 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 83 # BTF_KIND_INT(id = 9) -; CHECK-NEXT: .long 16777216 # 0x1000000 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 16777248 # 0x1000020 -; CHECK-NEXT: .long 87 # BTF_KIND_FUNC(id = 10) -; CHECK-NEXT: .long 201326594 # 0xc000002 -; CHECK-NEXT: .long 3 -; CHECK-NEXT: .long 92 # BTF_KIND_TYPE_TAG(id = 11) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 97 # BTF_KIND_TYPE_TAG(id = 12) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 11 +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 35 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 49 # BTF_KIND_STRUCT(id = 8) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 53 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 9) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 59 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 64 # BTF_KIND_TYPE_TAG(id = 11) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 69 # BTF_KIND_TYPE_TAG(id = 12) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 11 -; CHECK: .ascii "test" # string offset=1 -; CHECK: .ascii "map_value" # string offset=63 -; CHECK: .ascii "ptr" # string offset=73 -; CHECK: .ascii "foo" # string offset=77 -; CHECK: .byte 105 # string offset=81 -; CHECK: .ascii "int" # string offset=83 -; CHECK: .ascii "func" # string offset=87 -; CHECK: .ascii "tag2" # string offset=92 -; CHECK: .ascii "tag1" # string offset=97 +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=35 +; CHECK: .ascii "ptr" # string offset=45 +; CHECK: .ascii "foo" # string offset=49 +; CHECK: .byte 105 # string offset=53 +; CHECK: .ascii "int" # string offset=55 +; CHECK: .ascii "func" # string offset=59 +; CHECK: .ascii "tag2" # string offset=64 +; CHECK: .ascii "tag1" # string offset=69 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 -; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 -declare !dbg !27 dso_local void @func(%struct.map_value* noundef, %struct.foo* noundef) local_unnamed_addr #3 +declare !dbg !31 dso_local void @func(ptr noundef, ptr noundef) local_unnamed_addr #3 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 -attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } -attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } attributes #4 = { nounwind } @@ -116,13 +113,13 @@ !llvm.module.flags = !{!2, !3, !4, !5} !llvm.ident = !{!6} -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.c", directory: "/tmp//home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "8b3b8281c3b4240403467e0c9461251d") +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{i32 1, !"wchar_size", i32 4} !5 = !{i32 7, !"frame-pointer", i32 2} -!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!6 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} !7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !8, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) !8 = !DISubroutineType(types: !9) !9 = !{null} @@ -131,21 +128,27 @@ !12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 7, size: 64, elements: !13) !13 = !{!14} !14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 8, baseType: !15, size: 64) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20) -!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !24) +!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17, annotations: !21) !17 = !{!18} -!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !16, file: !1, line: 5, baseType: !19, size: 32) -!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!20 = !{!21, !22} -!21 = !{!"btf_type_tag", !"tag2"} -!22 = !{!"btf_type_tag", !"tag1"} -!23 = !DILocation(line: 13, column: 9, scope: !7) -!24 = !DILocation(line: 13, column: 26, scope: !7) -!25 = !DILocation(line: 14, column: 9, scope: !7) -!26 = !DILocation(line: 15, column: 1, scope: !7) -!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !32) -!28 = !DISubroutineType(types: !29) -!29 = !{null, !30, !31} -!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) -!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!32 = !{} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 5, baseType: !20, size: 32) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17) +!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!21 = !{!22, !23} +!22 = !{!"btf:type_tag", !"tag2"} +!23 = !{!"btf:type_tag", !"tag1"} +!24 = !{!25, !26} +!25 = !{!"btf_type_tag", !"tag2"} +!26 = !{!"btf_type_tag", !"tag1"} +!27 = !DILocation(line: 13, column: 9, scope: !7) +!28 = !DILocation(line: 13, column: 26, scope: !7) +!29 = !DILocation(line: 14, column: 9, scope: !7) +!30 = !DILocation(line: 15, column: 1, scope: !7) +!31 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !32, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !36) +!32 = !DISubroutineType(types: !33) +!33 = !{null, !34, !35} +!34 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!36 = !{!37, !38} +!37 = !DILocalVariable(arg: 1, scope: !31, file: !1, line: 10, type: !34) +!38 = !DILocalVariable(arg: 2, scope: !31, file: !1, line: 10, type: !35) diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-skip-var.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-skip-var.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-skip-var.ll @@ -0,0 +1,74 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; int __tag1 *aa; +; int __tag1 bb; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll +; +; BTF VAR entry for `b` should be stripped of type tag. + +@aa = dso_local global ptr null, align 8, !dbg !0 +@bb = dso_local global i32 0, align 4, !dbg !5 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15, !16, !17, !18, !19} +!llvm.ident = !{!20} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "aa", scope: !2, file: !3, line: 3, type: !10, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 034dbeecee00be5c47fc265333c6d58bb4801240)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/some/dir", checksumkind: CSK_MD5, checksum: "6abf72a79fc44e271d8676233a1f5ef5") +!4 = !{!0, !5} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "bb", scope: !2, file: !3, line: 4, type: !7, isLocal: false, isDefinition: true) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !8) +!8 = !{!9} +!9 = !{!"btf:type_tag", !"tag1"} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !11) +!11 = !{!12} +!12 = !{!"btf_type_tag", !"tag1"} +!13 = !{i32 7, !"Dwarf Version", i32 5} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{i32 8, !"PIC Level", i32 2} +!17 = !{i32 7, !"PIE Level", i32 2} +!18 = !{i32 7, !"uwtable", i32 2} +!19 = !{i32 7, !"frame-pointer", i32 2} +!20 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 034dbeecee00be5c47fc265333c6d58bb4801240)"} + +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; +; CHECK-NEXT: .long 5 # BTF_KIND_TYPE_TAG(id = 3) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 2 +; +; Variable 'aa': +; - name_off 10 corresponds to string "aa" +; - type 1 corresponds to int __tag1* +; CHECK-NEXT: .long 10 # BTF_KIND_VAR(id = 4) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; +; Variable 'bb': +; - name_off 13 corresponds to string "bb" +; - type 2 corresponds to int, type tag is not referenced +; CHECK-NEXT: .long 13 # BTF_KIND_VAR(id = 5) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "int" # string offset=1 +; CHECK: .ascii "tag1" # string offset=5 +; CHECK: .ascii "aa" # string offset=10 +; CHECK: .ascii "bb" # string offset=13 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll @@ -11,53 +11,62 @@ @g = dso_local local_unnamed_addr global ptr null, align 8, !dbg !0 !llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!12, !13, !14, !15} -!llvm.ident = !{!16} +!llvm.module.flags = !{!15, !16, !17, !18} +!llvm.ident = !{!19} !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type") +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "9ae91fe3dd8e44985841816e35923786") !4 = !{!0} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !10) -!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !8) -!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !13) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !10) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !8) !8 = !{!9} -!9 = !{!"btf_type_tag", !"tag1"} -!10 = !{!9, !11} -!11 = !{!"btf_type_tag", !"tag2"} +!9 = !{!"btf:type_tag", !"tag1"} +!10 = !{!9, !11, !12} +!11 = !{!"btf:type_tag", !"tag2"} +!12 = !{!"btf_type_tag", !"tag1"} +!13 = !{!12, !14} +!14 = !{!"btf_type_tag", !"tag2"} -; CHECK: .long 1 # BTF_KIND_TYPE_TAG(id = 1) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 2) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 3) +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) ; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 3) +; CHECK-NEXT: .long 301989888 # 0x12000000 ; CHECK-NEXT: .long 2 -; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 4) +; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 4) ; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 5) ; CHECK-NEXT: .long 16777216 # 0x1000000 ; CHECK-NEXT: .long 4 ; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 5 ; CHECK-NEXT: .long 15 # BTF_KIND_VAR(id = 7) ; CHECK-NEXT: .long 234881024 # 0xe000000 -; CHECK-NEXT: .long 3 ; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 17 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 8 ; CHECK: .ascii "tag1" # string offset=1 ; CHECK: .ascii "tag2" # string offset=6 ; CHECK: .ascii "int" # string offset=11 ; CHECK: .byte 103 # string offset=15 -!12 = !{i32 7, !"Dwarf Version", i32 4} -!13 = !{i32 2, !"Debug Info Version", i32 3} -!14 = !{i32 1, !"wchar_size", i32 4} -!15 = !{i32 7, !"frame-pointer", i32 2} -!16 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)"} +!15 = !{i32 7, !"Dwarf Version", i32 5} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{i32 7, !"frame-pointer", i32 2} +!19 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll @@ -0,0 +1,48 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; void __tag1 *foo; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +@foo = dso_local local_unnamed_addr global ptr null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13, !14, !15, !16} +!llvm.ident = !{!17} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 2, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git b0d4d11b535f4c3b730222013f4da5b0cbc4558a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "d51e2505a6f475a2c1811fd5e5fa9c49") +!4 = !{!0} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !9) +!6 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "void", annotations: !7) +!7 = !{!8} +!8 = !{!"btf:type_tag", !"tag1"} +!9 = !{!10} +!10 = !{!"btf_type_tag", !"tag1"} +!11 = !{i32 7, !"Dwarf Version", i32 5} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{i32 8, !"PIC Level", i32 2} +!15 = !{i32 7, !"PIE Level", i32 2} +!16 = !{i32 7, !"uwtable", i32 2} +!17 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git b0d4d11b535f4c3b730222013f4da5b0cbc4558a)"} + +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 2) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 0 +; ^^^ void type id +; CHECK-NEXT: .long 6 # BTF_KIND_VAR(id = 3) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "tag1" # string offset=1 +; CHECK: .ascii "foo" # string offset=6