[llvm] r367062 - [BPF] fix typedef issue for offset relocation

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 29 02:01:03 PDT 2019


Merged to release_90 in r367211.

On Thu, Jul 25, 2019 at 11:46 PM Yonghong Song via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: yhs
> Date: Thu Jul 25 14:47:27 2019
> New Revision: 367062
>
> URL: http://llvm.org/viewvc/llvm-project?rev=367062&view=rev
> Log:
> [BPF] fix typedef issue for offset relocation
>
> Currently, the CO-RE offset relocation does not work
> if any struct/union member or array element is a typedef.
> For example,
>   typedef const int arr_t[7];
>   struct input {
>       arr_t a;
>   };
>   func(...) {
>        struct input *in = ...;
>        ... __builtin_preserve_access_index(&in->a[1]) ...
>   }
> The BPF backend calculated default offset is 0 while
> 4 is the correct answer. Similar issues exist for struct/union
> typedef's.
>
> When getting struct/union member or array element type,
> we should trace down to the type by skipping typedef
> and qualifiers const/volatile as this is what clang did
> to generate getelementptr instructions.
> (const/volatile member type qualifiers are already
> ignored by clang.)
>
> This patch fixed this issue, for each access index,
> skipping typedef and const/volatile/restrict BTF types.
>
> Signed-off-by: Yonghong Song <yhs at fb.com>
>
> Differential Revision: https://reviews.llvm.org/D65259
>
> Added:
>     llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll
>     llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll
>     llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll
>     llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll
> Modified:
>     llvm/trunk/lib/Target/BPF/BTFDebug.cpp
>     llvm/trunk/lib/Target/BPF/BTFDebug.h
>
> Modified: llvm/trunk/lib/Target/BPF/BTFDebug.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BTFDebug.cpp?rev=367062&r1=367061&r2=367062&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/BPF/BTFDebug.cpp (original)
> +++ llvm/trunk/lib/Target/BPF/BTFDebug.cpp Thu Jul 25 14:47:27 2019
> @@ -30,6 +30,18 @@ static const char *BTFKindStr[] = {
>  #include "BTF.def"
>  };
>
> +static const DIType * stripQualifiers(const DIType *Ty) {
> +  while (const auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
> +    unsigned Tag = DTy->getTag();
> +    if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
> +        Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_restrict_type)
> +      break;
> +    Ty = DTy->getBaseType();
> +  }
> +
> +  return Ty;
> +}
> +
>  /// Emit a BTF common type.
>  void BTFTypeBase::emitType(MCStreamer &OS) {
>    OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) +
> @@ -184,9 +196,9 @@ void BTFTypeEnum::emitType(MCStreamer &O
>    }
>  }
>
> -BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t ElemSize,
> -                           uint32_t NumElems)
> -    : ElemSize(ElemSize) {
> +BTFTypeArray::BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId,
> +                           uint32_t ElemSize, uint32_t NumElems)
> +    : ElemTyNoQual(Ty), ElemSize(ElemSize) {
>    Kind = BTF::BTF_KIND_ARRAY;
>    BTFType.NameOff = 0;
>    BTFType.Info = Kind << 24;
> @@ -207,6 +219,9 @@ void BTFTypeArray::completeType(BTFDebug
>    // created during initial type traversal. Just
>    // retrieve that type id.
>    ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
> +
> +  ElemTypeNoQual = ElemTyNoQual ? BDebug.getTypeId(ElemTyNoQual)
> +                                : ArrayInfo.ElemType;
>  }
>
>  void BTFTypeArray::emitType(MCStreamer &OS) {
> @@ -218,7 +233,7 @@ void BTFTypeArray::emitType(MCStreamer &
>
>  void BTFTypeArray::getLocInfo(uint32_t Loc, uint32_t &LocOffset,
>                                uint32_t &ElementTypeId) {
> -  ElementTypeId = ArrayInfo.ElemType;
> +  ElementTypeId = ElemTypeNoQual;
>    LocOffset = Loc * ElemSize;
>  }
>
> @@ -251,7 +266,9 @@ void BTFTypeStruct::completeType(BTFDebu
>      } else {
>        BTFMember.Offset = DDTy->getOffsetInBits();
>      }
> -    BTFMember.Type = BDebug.getTypeId(DDTy->getBaseType());
> +    const auto *BaseTy = DDTy->getBaseType();
> +    BTFMember.Type = BDebug.getTypeId(BaseTy);
> +    MemberTypeNoQual.push_back(BDebug.getTypeId(stripQualifiers(BaseTy)));
>      Members.push_back(BTFMember);
>    }
>  }
> @@ -270,7 +287,7 @@ std::string BTFTypeStruct::getName() { r
>
>  void BTFTypeStruct::getMemberInfo(uint32_t Loc, uint32_t &MemberOffset,
>                                    uint32_t &MemberType) {
> -  MemberType = Members[Loc].Type;
> +  MemberType = MemberTypeNoQual[Loc];
>    MemberOffset =
>        HasBitField ? Members[Loc].Offset & 0xffffff : Members[Loc].Offset;
>  }
> @@ -492,10 +509,13 @@ void BTFDebug::visitArrayType(const DICo
>    uint32_t ElemTypeId, ElemSize;
>    const DIType *ElemType = CTy->getBaseType();
>    visitTypeEntry(ElemType, ElemTypeId, false, false);
> +
> +  // Strip qualifiers from element type to get accurate element size.
> +  ElemType = stripQualifiers(ElemType);
>    ElemSize = ElemType->getSizeInBits() >> 3;
>
>    if (!CTy->getSizeInBits()) {
> -    auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, 0, 0);
> +    auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemType, ElemTypeId, 0, 0);
>      ArrayTypes.push_back(TypeEntry.get());
>      ElemTypeId = addType(std::move(TypeEntry), CTy);
>    } else {
> @@ -507,9 +527,11 @@ void BTFDebug::visitArrayType(const DICo
>            const DISubrange *SR = cast<DISubrange>(Element);
>            auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
>            int64_t Count = CI->getSExtValue();
> +          const DIType *ArrayElemTy = (I == 0) ? ElemType : nullptr;
>
>            auto TypeEntry =
> -              llvm::make_unique<BTFTypeArray>(ElemTypeId, ElemSize, Count);
> +              llvm::make_unique<BTFTypeArray>(ArrayElemTy, ElemTypeId,
> +                                              ElemSize, Count);
>            ArrayTypes.push_back(TypeEntry.get());
>            if (I == 0)
>              ElemTypeId = addType(std::move(TypeEntry), CTy);
> @@ -1039,7 +1061,10 @@ void BTFDebug::generateOffsetReloc(const
>          Offset += LocOffset;
>          PrevArrayType = nullptr;
>          setTypeFromId(ElementTypeId, &PrevStructType, &PrevArrayType);
> +      } else {
> +        llvm_unreachable("Internal Error: BTF offset relocation type traversal error");
>        }
> +
>        Start = End + 1;
>        End = Start;
>      }
>
> Modified: llvm/trunk/lib/Target/BPF/BTFDebug.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BTFDebug.h?rev=367062&r1=367061&r2=367062&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/BPF/BTFDebug.h (original)
> +++ llvm/trunk/lib/Target/BPF/BTFDebug.h Thu Jul 25 14:47:27 2019
> @@ -104,11 +104,14 @@ public:
>
>  /// Handle array type.
>  class BTFTypeArray : public BTFTypeBase {
> +  const DIType *ElemTyNoQual;
>    uint32_t ElemSize;
>    struct BTF::BTFArray ArrayInfo;
> +  uint32_t ElemTypeNoQual;
>
>  public:
> -  BTFTypeArray(uint32_t ElemTypeId, uint32_t ElemSize, uint32_t NumElems);
> +  BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId,
> +               uint32_t ElemSize, uint32_t NumElems);
>    uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
>    void completeType(BTFDebug &BDebug);
>    void emitType(MCStreamer &OS);
> @@ -120,6 +123,7 @@ class BTFTypeStruct : public BTFTypeBase
>    const DICompositeType *STy;
>    bool HasBitField;
>    std::vector<struct BTF::BTFMember> Members;
> +  std::vector<uint32_t> MemberTypeNoQual;
>
>  public:
>    BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
>
> Added: llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll?rev=367062&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll (added)
> +++ llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll Thu Jul 25 14:47:27 2019
> @@ -0,0 +1,97 @@
> +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s
> +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s
> +;
> +; Source code:
> +;   typedef const int arr_t[7];
> +;   typedef arr_t __arr;
> +;   typedef __arr _arr;
> +;   struct __s { _arr a; };
> +;   typedef struct __s s;
> +;   #define _(x) (__builtin_preserve_access_index(x))
> +;   int get_value(const void *addr);
> +;   int test(s *arg) {
> +;     return get_value(_(&arg->a[1]));
> +;   }
> +; clang -target bpf -S -O2 -g -emit-llvm test.c
> +
> +%struct.__s = type { [7 x i32] }
> +
> +; Function Attrs: nounwind
> +define dso_local i32 @test(%struct.__s* %arg) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  call void @llvm.dbg.value(metadata %struct.__s* %arg, metadata !24, metadata !DIExpression()), !dbg !25
> +  %0 = tail call [7 x i32]* @llvm.preserve.struct.access.index.p0a7i32.p0s_struct.__ss(%struct.__s* %arg, i32 0, i32 0), !dbg !26, !llvm.preserve.access.index !13
> +  %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]* %0, i32 1, i32 1), !dbg !26
> +  %2 = bitcast i32* %1 to i8*, !dbg !26
> +  %call = tail call i32 @get_value(i8* %2) #4, !dbg !27
> +  ret i32 %call, !dbg !28
> +}
> +
> +; CHECK:        .cfi_startproc
> +; CHECK: [[RELOC:.Ltmp[0-9]+]]:
> +; CHECK:         r2 = 4
> +; CHECK:         r1 += r2
> +; CHECK:         call get_value
> +
> +; CHECK:         .long   {{[0-9]+}}              # BTF_KIND_STRUCT(id = [[TYPE_ID:[0-9]+]])
> +; CHECK:         .ascii  ".text"                 # string offset=[[SEC_INDEX:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .ascii  "0:0:1"                 # string offset=[[ACCESS_STR:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .long   12                      # OffsetReloc
> +; CHECK-NEXT:    .long   [[SEC_INDEX]]           # Offset reloc section string offset=[[SEC_INDEX]]
> +; CHECK-NEXT:    .long   1
> +; CHECK-NEXT:    .long   [[RELOC]]
> +; CHECK-NEXT:    .long   [[TYPE_ID]]
> +; CHECK-NEXT:    .long   [[ACCESS_STR]]
> +
> +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1
> +
> +; Function Attrs: nounwind readnone
> +declare [7 x i32]* @llvm.preserve.struct.access.index.p0a7i32.p0s_struct.__ss(%struct.__s*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone
> +declare i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.value(metadata, metadata, metadata) #3
> +
> +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind readnone speculatable }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
> +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"}
> +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !23)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
> +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13)
> +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__s", file: !1, line: 4, size: 224, elements: !14)
> +!14 = !{!15}
> +!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 4, baseType: !16, size: 224)
> +!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "_arr", file: !1, line: 3, baseType: !17)
> +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__arr", file: !1, line: 2, baseType: !18)
> +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr_t", file: !1, line: 1, baseType: !19)
> +!19 = !DICompositeType(tag: DW_TAG_array_type, baseType: !20, size: 224, elements: !21)
> +!20 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !10)
> +!21 = !{!22}
> +!22 = !DISubrange(count: 7)
> +!23 = !{!24}
> +!24 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11)
> +!25 = !DILocation(line: 0, scope: !7)
> +!26 = !DILocation(line: 9, column: 20, scope: !7)
> +!27 = !DILocation(line: 9, column: 10, scope: !7)
> +!28 = !DILocation(line: 9, column: 3, scope: !7)
>
> Added: llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll?rev=367062&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll (added)
> +++ llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-struct.ll Thu Jul 25 14:47:27 2019
> @@ -0,0 +1,90 @@
> +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s
> +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s
> +;
> +; Source code:
> +;   typedef int _int;
> +;   typedef _int __int;
> +;   struct __s { __int a; __int b; };
> +;   typedef struct __s _s;
> +;   typedef _s s;
> +;   #define _(x) (__builtin_preserve_access_index(x))
> +;   int get_value(const void *addr);
> +;   int test(s *arg) {
> +;     return get_value(_(&arg->b));
> +;   }
> +; clang -target bpf -S -O2 -g -emit-llvm test.c
> +
> +%struct.__s = type { i32, i32 }
> +
> +; Function Attrs: nounwind
> +define dso_local i32 @test(%struct.__s* %arg) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  call void @llvm.dbg.value(metadata %struct.__s* %arg, metadata !21, metadata !DIExpression()), !dbg !22
> +  %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ss(%struct.__s* %arg, i32 1, i32 1), !dbg !23, !llvm.preserve.access.index !14
> +  %1 = bitcast i32* %0 to i8*, !dbg !23
> +  %call = tail call i32 @get_value(i8* %1) #4, !dbg !24
> +  ret i32 %call, !dbg !25
> +}
> +
> +; CHECK:        .cfi_startproc
> +; CHECK:        [[RELOC:.Ltmp[0-9]+]]:
> +; CHECK:        r2 = 4
> +; CHECK:        r1 += r2
> +; CHECK:        call get_value
> +
> +; CHECK:        .long   {{[0-9]+}}              # BTF_KIND_STRUCT(id = [[TYPE_ID:[0-9]+]])
> +; CHECK:        .ascii  ".text"                 # string offset=[[SEC_STR:[0-9]+]]
> +; CHECK-NEXT:   .byte   0
> +; CHECK:        .ascii  "0:1"                   # string offset=[[ACCESS_STR:[0-9]+]]
> +; CHECK-NEXT:   .byte   0
> +; CHECK:        .long   12                      # OffsetReloc
> +; CHECK-NEXT:   .long   [[SEC_STR]]             # Offset reloc section string offset={{[0-9]+}}
> +; CHECK-NEXT:   .long   1
> +; CHECK-NEXT:   .long   [[RELOC]]
> +; CHECK-NEXT:   .long   [[TYPE_ID]]
> +; CHECK-NEXT:   .long   [[ACCESS_STR]]
> +
> +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1
> +
> +; Function Attrs: nounwind readnone
> +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.__ss(%struct.__s*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.value(metadata, metadata, metadata) #3
> +
> +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind readnone speculatable }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
> +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"}
> +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !20)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
> +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13)
> +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "_s", file: !1, line: 4, baseType: !14)
> +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__s", file: !1, line: 3, size: 64, elements: !15)
> +!15 = !{!16, !19}
> +!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 3, baseType: !17, size: 32)
> +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !18)
> +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !10)
> +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 3, baseType: !17, size: 32, offset: 32)
> +!20 = !{!21}
> +!21 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11)
> +!22 = !DILocation(line: 0, scope: !7)
> +!23 = !DILocation(line: 9, column: 20, scope: !7)
> +!24 = !DILocation(line: 9, column: 10, scope: !7)
> +!25 = !DILocation(line: 9, column: 3, scope: !7)
>
> Added: llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll?rev=367062&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll (added)
> +++ llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef-union.ll Thu Jul 25 14:47:27 2019
> @@ -0,0 +1,90 @@
> +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s
> +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s
> +;
> +; Source code:
> +;   typedef int _int;
> +;   typedef _int __int;
> +;   union __s { __int a; __int b; };
> +;   typedef union __s _s;
> +;   typedef _s s;
> +;   #define _(x) (__builtin_preserve_access_index(x))
> +;   int get_value(const void *addr);
> +;   int test(s *arg) {
> +;     return get_value(_(&arg->b));
> +;   }
> +; clang -target bpf -S -O2 -g -emit-llvm test.c
> +
> +%union.__s = type { i32 }
> +
> +; Function Attrs: nounwind
> +define dso_local i32 @test(%union.__s* %arg) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  call void @llvm.dbg.value(metadata %union.__s* %arg, metadata !21, metadata !DIExpression()), !dbg !22
> +  %0 = tail call %union.__s* @llvm.preserve.union.access.index.p0s_union.__ss.p0s_union.__ss(%union.__s* %arg, i32 1), !dbg !23, !llvm.preserve.access.index !14
> +  %1 = bitcast %union.__s* %0 to i8*, !dbg !23
> +  %call = tail call i32 @get_value(i8* %1) #4, !dbg !24
> +  ret i32 %call, !dbg !25
> +}
> +
> +; CHECK:        .cfi_startproc
> +; CHECK: [[RELOC:.Ltmp[0-9]+]]:
> +; CHECK:         r2 = 0
> +; CHECK:         r1 += r2
> +; CHECK:         call get_value
> +
> +; CHECK:         .long   {{[0-9]+}}              # BTF_KIND_UNION(id = [[TYPE_ID:[0-9]+]])
> +; CHECK:         .ascii  ".text"                 # string offset=[[SEC_INDEX:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .ascii  "0:1"                   # string offset=[[ACCESS_STR:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .long   12                      # OffsetReloc
> +; CHECK-NEXT:    .long   [[SEC_INDEX]]           # Offset reloc section string offset=[[SEC_INDEX]]
> +; CHECK-NEXT:    .long   1
> +; CHECK-NEXT:    .long   [[RELOC]]
> +; CHECK-NEXT:    .long   [[TYPE_ID]]
> +; CHECK-NEXT:    .long   [[ACCESS_STR]]
> +
> +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1
> +
> +; Function Attrs: nounwind readnone
> +declare %union.__s* @llvm.preserve.union.access.index.p0s_union.__ss.p0s_union.__ss(%union.__s*, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.value(metadata, metadata, metadata) #3
> +
> +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind readnone speculatable }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
> +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"}
> +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !20)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
> +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !13)
> +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "_s", file: !1, line: 4, baseType: !14)
> +!14 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "__s", file: !1, line: 3, size: 32, elements: !15)
> +!15 = !{!16, !19}
> +!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 3, baseType: !17, size: 32)
> +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !18)
> +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !10)
> +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !14, file: !1, line: 3, baseType: !17, size: 32)
> +!20 = !{!21}
> +!21 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 8, type: !11)
> +!22 = !DILocation(line: 0, scope: !7)
> +!23 = !DILocation(line: 9, column: 20, scope: !7)
> +!24 = !DILocation(line: 9, column: 10, scope: !7)
> +!25 = !DILocation(line: 9, column: 3, scope: !7)
>
> Added: llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll?rev=367062&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll (added)
> +++ llvm/trunk/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll Thu Jul 25 14:47:27 2019
> @@ -0,0 +1,111 @@
> +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck %s
> +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck %s
> +;
> +; Source code:
> +;   struct s { int a; int b; };
> +;   typedef struct s __s;
> +;   union u { __s c; __s d; };
> +;   typedef union u __u;
> +;   typedef __u arr_t[7];
> +;   typedef arr_t __arr;
> +;
> +;   #define _(x) (__builtin_preserve_access_index(x))
> +;   int get_value(const void *addr);
> +;   int test(__arr *arg) {
> +;     return get_value(_(&arg[1]->d.b));
> +;   }
> +; clang -target bpf -S -O2 -g -emit-llvm test.c
> +; The offset reloc offset should be 12 from the base "arg".
> +
> +%union.u = type { %struct.s }
> +%struct.s = type { i32, i32 }
> +
> +; Function Attrs: nounwind
> +define dso_local i32 @test([7 x %union.u]* %arg) local_unnamed_addr #0 !dbg !7 {
> +entry:
> +  call void @llvm.dbg.value(metadata [7 x %union.u]* %arg, metadata !28, metadata !DIExpression()), !dbg !29
> +  %0 = tail call [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]* %arg, i32 0, i32 1), !dbg !30
> +  %arraydecay = getelementptr inbounds [7 x %union.u], [7 x %union.u]* %0, i64 0, i64 0, !dbg !30
> +  %1 = tail call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %arraydecay, i32 1), !dbg !30, !llvm.preserve.access.index !16
> +  %d = getelementptr inbounds %union.u, %union.u* %1, i64 0, i32 0, !dbg !30
> +  %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* %d, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !20
> +  %3 = bitcast i32* %2 to i8*, !dbg !30
> +  %call = tail call i32 @get_value(i8* %3) #4, !dbg !31
> +  ret i32 %call, !dbg !32
> +}
> +
> +; CHECK:         .cfi_startproc
> +; CHECK: [[RELOC:.Ltmp[0-9]+]]:
> +; CHECK:         r2 = 12
> +; CHECK:         r1 += r2
> +; CHECK:         call get_value
> +
> +; CHECK:         .long   {{[0-9]+}}              # BTF_KIND_UNION(id = [[TYPE_ID:[0-9]+]])
> +; CHECK:         .ascii  ".text"                 # string offset=[[SEC_STR:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .ascii  "1:1:1"                 # string offset=[[ACCESS_STR:[0-9]+]]
> +; CHECK-NEXT:    .byte   0
> +; CHECK:         .long   12                      # OffsetReloc
> +; CHECK-NEXT:    .long   [[SEC_STR:[0-9]+]]      # Offset reloc section string offset=[[SEC_STR:[0-9]+]]
> +; CHECK-NEXT:    .long   1
> +; CHECK-NEXT:    .long   [[RELOC:.Ltmp[0-9]+]]
> +; CHECK-NEXT:    .long   [[TYPE_ID:[0-9]+]]
> +; CHECK-NEXT:    .long   [[ACCESS_STR:[0-9]+]]
> +
> +declare dso_local i32 @get_value(i8*) local_unnamed_addr #1
> +
> +; Function Attrs: nounwind readnone
> +declare [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone
> +declare %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u*, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone
> +declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s*, i32 immarg, i32 immarg) #2
> +
> +; Function Attrs: nounwind readnone speculatable
> +declare void @llvm.dbg.value(metadata, metadata, metadata) #3
> +
> +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind readnone speculatable }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!3, !4, !5}
> +!llvm.ident = !{!6}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
> +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/core-bugs")
> +!2 = !{}
> +!3 = !{i32 2, !"Dwarf Version", i32 4}
> +!4 = !{i32 2, !"Debug Info Version", i32 3}
> +!5 = !{i32 1, !"wchar_size", i32 4}
> +!6 = !{!"clang version 10.0.0 (trunk 366831) (llvm/trunk 366867)"}
> +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !8, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27)
> +!8 = !DISubroutineType(types: !9)
> +!9 = !{!10, !11}
> +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
> +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
> +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__arr", file: !1, line: 6, baseType: !13)
> +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr_t", file: !1, line: 5, baseType: !14)
> +!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 448, elements: !25)
> +!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "__u", file: !1, line: 4, baseType: !16)
> +!16 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u", file: !1, line: 3, size: 64, elements: !17)
> +!17 = !{!18, !24}
> +!18 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !16, file: !1, line: 3, baseType: !19, size: 64)
> +!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__s", file: !1, line: 2, baseType: !20)
> +!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 64, elements: !21)
> +!21 = !{!22, !23}
> +!22 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !20, file: !1, line: 1, baseType: !10, size: 32)
> +!23 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !20, file: !1, line: 1, baseType: !10, size: 32, offset: 32)
> +!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !16, file: !1, line: 3, baseType: !19, size: 64)
> +!25 = !{!26}
> +!26 = !DISubrange(count: 7)
> +!27 = !{!28}
> +!28 = !DILocalVariable(name: "arg", arg: 1, scope: !7, file: !1, line: 10, type: !11)
> +!29 = !DILocation(line: 0, scope: !7)
> +!30 = !DILocation(line: 11, column: 20, scope: !7)
> +!31 = !DILocation(line: 11, column: 10, scope: !7)
> +!32 = !DILocation(line: 11, column: 3, scope: !7)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list