[llvm] [BPF] Skip modifiers for __builtin_btf_type_id() local type (PR #71094)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 2 11:48:33 PDT 2023


https://github.com/yonghong-song created https://github.com/llvm/llvm-project/pull/71094

BPF upstream reported an inconsistent behavior w.r.t. BPF_TYPE_ID_LOCAL vs. BPF_TYPE_ID_TARGET (or BPF_TYPE_ID_REMOTE in LLVM terminology).

For BPF_TYPE_ID_TARGET, all modifiers (like 'const' and 'volatile') are ignored in the final type encoding. For example, for type
 'const struct foo', the eventually encoding in BTF relocation
is 'struct foo'. This faciliates libbpf to match corresponding kernel types with considering any modifiers.

Currently behavior for BPF_TYPE_ID_LOCAL is different. It will encode 'const struct foo' in BTF relocation and such discrepancy confused users ([1]).

This patch fixed this discrepancy by making BPF_TYPE_ID_LOCAL BTF type representation the sams as BPF_TYPE_ID_TARGET. This should have minimum user impact since ultimately user wants to get a real time not a 'const' type modifier.

The selftest builtin-btf-type-id-2.ll is used to test BPF_TYPE_ID_TARGET with 'const' modifier. Adapt the same test for BPF_TYPE_ID_LOCAL. And the below diff shows now both BPF_TYPE_ID_LOCAL and BPF_TYPE_ID_TARGET produces the same type:

  $ diff test/CodeGen/BPF/BTF/builtin-btf-type-id-2.ll test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll
  --- test/CodeGen/BPF/BTF/builtin-btf-type-id-2.ll       2023-07-30 16:58:20.657528310 -0700
  +++ test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll   2023-11-02 10:23:25.356959008 -0700
  @@ -6,7 +6,7 @@
   ;     int a;
   ;   };
   ;   int test(void) {
  -;     return __builtin_btf_type_id(*(const struct s *)0, 1);
  +;     return __builtin_btf_type_id(*(const struct s *)0, 0);
   ;   }
   ; Compilation flag:
   ;   clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c
  $

  [1] https://lore.kernel.org/bpf/CAN+4W8h3yDjkOLJPiuKVKTpj_08pBz8ke6vN=Lf8gcA=iYBM-g@mail.gmail.com/

>From c0ae308d2dae4bf96d7ecfdfa9270a0ed4e75576 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Thu, 2 Nov 2023 11:42:23 -0700
Subject: [PATCH] [BPF] Skip modifiers for __builtin_btf_type_id() local type

BPF upstream reported an inconsistent behavior w.r.t.
BPF_TYPE_ID_LOCAL vs. BPF_TYPE_ID_TARGET (or BPF_TYPE_ID_REMOTE
in LLVM terminology).

For BPF_TYPE_ID_TARGET, all modifiers (like 'const' and 'volatile')
are ignored in the final type encoding. For example, for type
 'const struct foo', the eventually encoding in BTF relocation
is 'struct foo'. This faciliates libbpf to match corresponding
kernel types with considering any modifiers.

Currently behavior for BPF_TYPE_ID_LOCAL is different.
It will encode 'const struct foo' in BTF relocation and such
discrepancy confused users ([1]).

This patch fixed this discrepancy by making BPF_TYPE_ID_LOCAL
BTF type representation the sams as BPF_TYPE_ID_TARGET.
This should have minimum user impact since ultimately user
wants to get a real time not a 'const' type modifier.

The selftest builtin-btf-type-id-2.ll is used to test
BPF_TYPE_ID_TARGET with 'const' modifier. Adapt the same test
for BPF_TYPE_ID_LOCAL. And the below diff shows now both
BPF_TYPE_ID_LOCAL and BPF_TYPE_ID_TARGET produces the same type:

  $ diff test/CodeGen/BPF/BTF/builtin-btf-type-id-2.ll test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll
  --- test/CodeGen/BPF/BTF/builtin-btf-type-id-2.ll       2023-07-30 16:58:20.657528310 -0700
  +++ test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll   2023-11-02 10:23:25.356959008 -0700
  @@ -6,7 +6,7 @@
   ;     int a;
   ;   };
   ;   int test(void) {
  -;     return __builtin_btf_type_id(*(const struct s *)0, 1);
  +;     return __builtin_btf_type_id(*(const struct s *)0, 0);
   ;   }
   ; Compilation flag:
   ;   clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c
  $
---
 llvm/lib/Target/BPF/BPFPreserveDIType.cpp     | 19 ++---
 .../BPF/BTF/builtin-btf-type-id-local.ll      | 73 +++++++++++++++++++
 2 files changed, 83 insertions(+), 9 deletions(-)
 create mode 100644 llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll

diff --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
index 78e1bf90f1bd524..fc4fb4d8f8001b3 100644
--- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
+++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
@@ -86,15 +86,16 @@ static bool BPFPreserveDITypeImpl(Function &F) {
       Reloc = BTF::BTF_TYPE_ID_LOCAL;
     } else {
       Reloc = BTF::BTF_TYPE_ID_REMOTE;
-      DIType *Ty = cast<DIType>(MD);
-      while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
-        unsigned Tag = DTy->getTag();
-        if (Tag != dwarf::DW_TAG_const_type &&
-            Tag != dwarf::DW_TAG_volatile_type)
-          break;
-        Ty = DTy->getBaseType();
-      }
+    }
+    DIType *Ty = cast<DIType>(MD);
+    while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+      unsigned Tag = DTy->getTag();
+      if (Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type)
+        break;
+      Ty = DTy->getBaseType();
+    }
 
+    if (Reloc == BTF::BTF_TYPE_ID_REMOTE) {
       if (Ty->getName().empty()) {
         if (isa<DISubroutineType>(Ty))
           report_fatal_error(
@@ -102,8 +103,8 @@ static bool BPFPreserveDITypeImpl(Function &F) {
         else
           report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
       }
-      MD = Ty;
     }
+    MD = Ty;
 
     BasicBlock *BB = Call->getParent();
     IntegerType *VarType = Type::getInt64Ty(BB->getContext());
diff --git a/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll
new file mode 100644
index 000000000000000..763b7345dcb8330
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-local.ll
@@ -0,0 +1,73 @@
+; RUN: opt -O2 -mtriple=bpf-pc-linux -S -o %t1 %s
+; RUN: llc -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s
+; RUN: llc -mattr=+alu32 -filetype=asm -o - %t1 | FileCheck -check-prefixes=CHECK %s
+; Source code:
+;   struct s {
+;     int a;
+;   };
+;   int test(void) {
+;     return __builtin_btf_type_id(*(const struct s *)0, 0);
+;   }
+; Compilation flag:
+;   clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c
+
+; Function Attrs: nounwind
+define dso_local i32 @test() #0 !dbg !7 {
+entry:
+  %0 = call i64 @llvm.bpf.btf.type.id(i32 0, i64 1), !dbg !11, !llvm.preserve.access.index !12
+  %conv = trunc i64 %0 to i32, !dbg !11
+  ret i32 %conv, !dbg !16
+}
+
+; CHECK:             .long   1                               # BTF_KIND_INT(id = 2)
+; CHECK-NEXT:        .long   16777216                        # 0x1000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   16777248                        # 0x1000020
+
+; CHECK:             .long   16                              # BTF_KIND_STRUCT(id = 4)
+; CHECK-NEXT:        .long   67108865                        # 0x4000001
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   18
+; CHECK-NEXT:        .long   2
+
+; CHECK:             .ascii  "int"                           # string offset=1
+; CHECK:             .ascii  ".text"                         # string offset=10
+; CHECK:             .byte   115                             # string offset=16
+; CHECK:             .byte   97                              # string offset=18
+; CHECK:             .byte   48                              # string offset=20
+
+; CHECK:             .long   16                              # FieldReloc
+; CHECK-NEXT:        .long   10                              # Field reloc section string offset=10
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   .Ltmp{{[0-9]+}}
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   20
+; CHECK-NEXT:        .long   7
+
+; Function Attrs: nounwind readnone
+declare i64 @llvm.bpf.btf.type.id(i32, i64) #1
+
+attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { nounwind readnone }
+
+!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 13.0.0 (https://github.com/llvm/llvm-project.git 9783e2098800b954c55ae598a1ce5c4b93444fc0)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/bpf/test")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9783e2098800b954c55ae598a1ce5c4b93444fc0)"}
+!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !DILocation(line: 5, column: 10, scope: !7)
+!12 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13)
+!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 1, size: 32, elements: !14)
+!14 = !{!15}
+!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 2, baseType: !10, size: 32)
+!16 = !DILocation(line: 5, column: 3, scope: !7)



More information about the llvm-commits mailing list