[llvm] [BPF] Fix CORE optimization bug in BPFMISimplifyPatchable (PR #183446)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 6 11:50:06 PST 2026


https://github.com/yonghong-song updated https://github.com/llvm/llvm-project/pull/183446

>From aa6829c6953469228d7fe851173adb94bb3c7138 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Wed, 25 Feb 2026 13:29:44 -0800
Subject: [PATCH] [BPF] Fix CORE optimization bug in BPFMISimplifyPatchable

Commit ffd57408efd4 ("[BPF] Enable relocation location for load/store/shifts")
enabled CORE relocation for load/store/shirts. In particular, the commit
did optimization to have load/store/shift insn itself having the relocation.
For the load and store, the optimization has the following:
  rX = *(rY + <relocation>) and *(rX + <relocation>) = rY
There is no value-range check for the above '<relocation>'.
For example, if the original '<relocation>' is 0x10006 due to a large
struct, the insn encoding of '<relocaiton>' will be truncated into '6'
and incorrect result will happen.

This patch fixed the issue by checking the value range of '<relocation>'.
If the '<relocation>' is more than INT16_MAX, optimization will be
skipped.

Even llvm side is fixed, libbpf side may still have issues with the
current approach since libbpf may change the value of <relocation>.
If the <relocation> value is more than INT16_MAX, libbpf will either
fail or need to patch insns.

Let us say we have
  rX = *(rY + <relocation>) and *(rX + <relocation>) = rY
libbpf will modify '<relocation>' value depending on the actual
offset in kernel data structure. If '<relocation>' is more
than INT16_MAX, more than one insn will be necessary.
llvm could add nop instructions for patch purpose (see [1]).

The following are major patching cases:
  case 1: rX = *(rY + <relocation>) // rX and rY are different
    rX = <relocation>
    rX += rY
    rX = *(rX + 0)
  case 2: rX = *(rX + <relocation>)
    rX += <relocation>
    rX = *(rX + 0)
  case 3: *(rX + <relocation>) = imm
    rX += <relocation>
    *(rX + 0) = imm
    rX -= <relocation>
  case 4: *(rX + <relocation>) = rY // rX and rY are different
    rX += <relocation>
    *(rX + 0) = rY
    rX -= <relocation>
  case 5: *(rX + <relocation>) = rX
    // We are not able to resolve this issue.

A llvm option (-disable-bpf-core-optimization) is implemented to
disable bpf core optimizaiton, which means the relocation will not
be in load/store insns. This can workaround the above case 5.

 [1] https://github.com/llvm/llvm-project/compare/main...yonghong-song:llvm-project:fix-core-overflow-debug
---
 .../lib/Target/BPF/BPFMISimplifyPatchable.cpp |  25 +++-
 .../CORE/offset-reloc-simplify-patchable-4.ll | 123 ++++++++++++++++++
 .../CORE/offset-reloc-simplify-patchable-5.ll | 123 ++++++++++++++++++
 3 files changed, 268 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-4.ll
 create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-5.ll

diff --git a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp
index 9d6de2044b2b6..991998105afec 100644
--- a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp
+++ b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp
@@ -42,6 +42,10 @@ using namespace llvm;
 
 #define DEBUG_TYPE "bpf-mi-simplify-patchable"
 
+static cl::opt<bool>
+    DisableCOREOptimization("disable-bpf-core-optimization", cl::Hidden,
+                            cl::desc("Disable CORE relocation optimization"));
+
 namespace {
 
 struct BPFMISimplifyPatchable : public MachineFunctionPass {
@@ -293,9 +297,24 @@ void BPFMISimplifyPatchable::processInst(MachineRegisterInfo *MRI,
     return;
   }
 
-  if (Opcode == BPF::ADD_rr)
-    checkADDrr(MRI, RelocOp, GVal);
-  else if (Opcode == BPF::SLL_rr)
+  if (DisableCOREOptimization)
+    return;
+
+  if (Opcode == BPF::ADD_rr) {
+    // If the struct offset is greater than INT16_MAX, skip optimization.
+    StringRef AccessPattern = GVal->getName();
+    size_t FirstDollar = AccessPattern.find_first_of('$');
+    size_t FirstColon = AccessPattern.find_first_of(':');
+    size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1);
+    StringRef PatchImmStr =
+        AccessPattern.substr(SecondColon + 1, FirstDollar - SecondColon);
+    int PatchImm = std::stoll(std::string(PatchImmStr));
+    if (PatchImm <= INT16_MAX)
+      checkADDrr(MRI, RelocOp, GVal);
+    return;
+  }
+
+  if (Opcode == BPF::SLL_rr)
     checkShift(MRI, *Inst->getParent(), RelocOp, GVal, BPF::SLL_ri);
   else if (Opcode == BPF::SRA_rr)
     checkShift(MRI, *Inst->getParent(), RelocOp, GVal, BPF::SRA_ri);
diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-4.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-4.ll
new file mode 100644
index 0000000000000..62e0c2cae0f46
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-4.ll
@@ -0,0 +1,123 @@
+; RUN: llc -mtriple=bpf -filetype=obj -mcpu=v3 %s -o %t
+; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t
+; RUN: %python %p/../BTF/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
+; RUN: llvm-objdump --no-print-imm-hex -dr --no-show-raw-insn %t | FileCheck --check-prefix=CHECK-DUMP %s
+
+; Source:
+;   struct t {
+;     char c[40000];
+;     int ub;
+;   } __attribute__((preserve_access_index));
+;   void foo(volatile struct t *t) {
+;     t->ub = 1;
+;   }
+;   int bar(volatile struct t *t) {
+;     return t->ub;
+;   }
+; Using the following command:
+;   clang -g -O2 -mcpu=v3 -S -emit-llvm --target=bpf t.c -o t.ll
+
+@"llvm.t:0:40000$0:1" = external global i64, !llvm.preserve.access.index !0 #0
+
+; Function Attrs: nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none)
+define dso_local void @foo(ptr noundef %0) local_unnamed_addr #1 !dbg !20 {
+    #dbg_value(ptr %0, !26, !DIExpression(), !27)
+  %2 = load i64, ptr @"llvm.t:0:40000$0:1", align 8
+  %3 = getelementptr i8, ptr %0, i64 %2
+  %4 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %3)
+  store volatile i32 1, ptr %4, align 4, !dbg !28, !tbaa !29
+  ret void, !dbg !31
+}
+
+; Function Attrs: nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none)
+define dso_local i32 @bar(ptr noundef %0) local_unnamed_addr #1 !dbg !32 {
+    #dbg_value(ptr %0, !36, !DIExpression(), !37)
+  %2 = load i64, ptr @"llvm.t:0:40000$0:1", align 8
+  %3 = getelementptr i8, ptr %0, i64 %2
+  %4 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 1, ptr %3)
+  %5 = load volatile i32, ptr %4, align 4, !dbg !38, !tbaa !29
+  ret i32 %5, !dbg !39
+}
+
+; CHECK-BTF:      [1] PTR '(anon)' type_id=2
+; CHECK-BTF-NEXT: [2] VOLATILE '(anon)' type_id=3
+; CHECK-BTF-NEXT: [3] STRUCT 't' size=40004 vlen=2
+; CHECK-BTF-NEXT:         'c' type_id=5 bits_offset=0
+; CHECK-BTF-NEXT:         'ub' type_id=7 bits_offset=320000
+; CHECK-BTF-NEXT: [4] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=SIGNED
+; CHECK-BTF-NEXT: [5] ARRAY '(anon)' type_id=4 index_type_id=6 nr_elems=40000
+; CHECK-BTF-NEXT: [6] INT '__ARRAY_SIZE_TYPE__' size=4 bits_offset=0 nr_bits=32 encoding=(none)
+; CHECK-BTF-NEXT: [7] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+; CHECK-BTF-NEXT: [8] FUNC_PROTO '(anon)' ret_type_id=0 vlen=1
+; CHECK-BTF-NEXT:         't' type_id=1
+; CHECK-BTF-NEXT: [9] FUNC 'foo' type_id=8 linkage=global
+; CHECK-BTF-NEXT: [10] FUNC_PROTO '(anon)' ret_type_id=7 vlen=1
+; CHECK-BTF-NEXT:          't' type_id=1
+; CHECK-BTF-NEXT: [11] FUNC 'bar' type_id=10 linkage=global
+
+; CHECK-DUMP:      <foo>:
+; CHECK-DUMP-NEXT: 0:       r2 = 40000
+; CHECK-DUMP-NEXT:          0000000000000000:  CO-RE <byte_off> [3] struct t::ub (0:1)
+; CHECK-DUMP-NEXT: 1:       r1 += r2
+; CHECK-DUMP-NEXT: 2:       w2 = 1
+; CHECK-DUMP-NEXT: 3:       *(u32 *)(r1 + 0) = w2
+; CHECK-DUMP-NEXT: 4:       exit
+; CHECK-DUMP:      <bar>:
+; CHECK-DUMP-NEXT: 5:       r2 = 40000
+; CHECK-DUMP-NEXT:          0000000000000028:  CO-RE <byte_off> [3] struct t::ub (0:1)
+; CHECK-DUMP-NEXT: 6:       r1 += r2
+; CHECK-DUMP-NEXT: 7:       w0 = *(u32 *)(r1 + 0)
+; CHECK-DUMP-NEXT: 8:       exit
+
+; Function Attrs: nofree nosync nounwind memory(none)
+declare ptr @llvm.bpf.passthrough.p0.p0(i32, ptr) #2
+
+attributes #0 = { "btf_ama" }
+attributes #1 = { nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="v3" }
+attributes #2 = { nofree nosync nounwind memory(none) }
+
+!llvm.dbg.cu = !{!10}
+!llvm.module.flags = !{!11, !12, !13, !14}
+!llvm.ident = !{!15}
+!llvm.errno.tbaa = !{!16}
+
+!0 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !1, line: 1, size: 320032, elements: !2)
+!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/tmp", checksumkind: CSK_MD5, checksum: "80fd4c64ef78a956ea2b9ea665675989")
+!2 = !{!3, !8}
+!3 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !0, file: !1, line: 2, baseType: !4, size: 320000)
+!4 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 320000, elements: !6)
+!5 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!6 = !{!7}
+!7 = !DISubrange(count: 40000)
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "ub", scope: !0, file: !1, line: 3, baseType: !9, size: 32, offset: 320000)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 23.0.0git (https://github.com/llvm/llvm-project.git 11727c11f833873af97d3969483f488e5251f35d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!11 = !{i32 7, !"Dwarf Version", i32 5}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+!13 = !{i32 7, !"frame-pointer", i32 2}
+!14 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!15 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git 11727c11f833873af97d3969483f488e5251f35d)"}
+!16 = !{!17, !17, i64 0}
+!17 = !{!"int", !18, i64 0}
+!18 = !{!"omnipotent char", !19, i64 0}
+!19 = !{!"Simple C/C++ TBAA"}
+!20 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 5, type: !21, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !10, retainedNodes: !25, keyInstructions: true)
+!21 = !DISubroutineType(types: !22)
+!22 = !{null, !23}
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64)
+!24 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !0)
+!25 = !{!26}
+!26 = !DILocalVariable(name: "t", arg: 1, scope: !20, file: !1, line: 5, type: !23)
+!27 = !DILocation(line: 0, scope: !20)
+!28 = !DILocation(line: 6, column: 9, scope: !20, atomGroup: 1, atomRank: 1)
+!29 = !{!30, !17, i64 40000}
+!30 = !{!"t", !18, i64 0, !17, i64 40000}
+!31 = !DILocation(line: 7, column: 1, scope: !20, atomGroup: 2, atomRank: 1)
+!32 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !33, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !10, retainedNodes: !35, keyInstructions: true)
+!33 = !DISubroutineType(types: !34)
+!34 = !{!9, !23}
+!35 = !{!36}
+!36 = !DILocalVariable(name: "t", arg: 1, scope: !32, file: !1, line: 8, type: !23)
+!37 = !DILocation(line: 0, scope: !32)
+!38 = !DILocation(line: 9, column: 13, scope: !32, atomGroup: 1, atomRank: 2)
+!39 = !DILocation(line: 9, column: 3, scope: !32, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-5.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-5.ll
new file mode 100644
index 0000000000000..ecd0c929524c1
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-5.ll
@@ -0,0 +1,123 @@
+; RUN: llc -mtriple=bpf -filetype=obj -mcpu=v3 -disable-bpf-core-optimization %s -o %t
+; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t
+; RUN: %python %p/../BTF/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
+; RUN: llvm-objdump --no-print-imm-hex -dr --no-show-raw-insn %t | FileCheck --check-prefix=CHECK-DUMP %s
+
+; Source:
+;   struct t {
+;     char c[40];
+;     int ub;
+;   } __attribute__((preserve_access_index));
+;   void foo(volatile struct t *t) {
+;     t->ub = 1;
+;   }
+;   int bar(volatile struct t *t) {
+;     return t->ub;
+;   }
+; Using the following command:
+;   clang -g -O2 -mcpu=v3 -S -emit-llvm --target=bpf t.c -o t.ll
+
+@"llvm.t:0:40$0:1" = external global i64, !llvm.preserve.access.index !0 #0
+
+; Function Attrs: nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none)
+define dso_local void @foo(ptr noundef %0) local_unnamed_addr #1 !dbg !20 {
+    #dbg_value(ptr %0, !26, !DIExpression(), !27)
+  %2 = load i64, ptr @"llvm.t:0:40$0:1", align 8
+  %3 = getelementptr i8, ptr %0, i64 %2
+  %4 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %3)
+  store volatile i32 1, ptr %4, align 4, !dbg !28, !tbaa !29
+  ret void, !dbg !31
+}
+
+; Function Attrs: nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none)
+define dso_local i32 @bar(ptr noundef %0) local_unnamed_addr #1 !dbg !32 {
+    #dbg_value(ptr %0, !36, !DIExpression(), !37)
+  %2 = load i64, ptr @"llvm.t:0:40$0:1", align 8
+  %3 = getelementptr i8, ptr %0, i64 %2
+  %4 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 1, ptr %3)
+  %5 = load volatile i32, ptr %4, align 4, !dbg !38, !tbaa !29
+  ret i32 %5, !dbg !39
+}
+
+; CHECK-BTF:      [1] PTR '(anon)' type_id=2
+; CHECK-BTF-NEXT: [2] VOLATILE '(anon)' type_id=3
+; CHECK-BTF-NEXT: [3] STRUCT 't' size=44 vlen=2
+; CHECK-BTF-NEXT:         'c' type_id=5 bits_offset=0
+; CHECK-BTF-NEXT:         'ub' type_id=7 bits_offset=320
+; CHECK-BTF-NEXT: [4] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=SIGNED
+; CHECK-BTF-NEXT: [5] ARRAY '(anon)' type_id=4 index_type_id=6 nr_elems=40
+; CHECK-BTF-NEXT: [6] INT '__ARRAY_SIZE_TYPE__' size=4 bits_offset=0 nr_bits=32 encoding=(none)
+; CHECK-BTF-NEXT: [7] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+; CHECK-BTF-NEXT: [8] FUNC_PROTO '(anon)' ret_type_id=0 vlen=1
+; CHECK-BTF-NEXT:         't' type_id=1
+; CHECK-BTF-NEXT: [9] FUNC 'foo' type_id=8 linkage=global
+; CHECK-BTF-NEXT: [10] FUNC_PROTO '(anon)' ret_type_id=7 vlen=1
+; CHECK-BTF-NEXT:          't' type_id=1
+; CHECK-BTF-NEXT: [11] FUNC 'bar' type_id=10 linkage=global
+
+; CHECK-DUMP:      <foo>:
+; CHECK-DUMP-NEXT: 0:       r2 = 40
+; CHECK-DUMP-NEXT:          0000000000000000:  CO-RE <byte_off> [3] struct t::ub (0:1)
+; CHECK-DUMP-NEXT: 1:       r1 += r2
+; CHECK-DUMP-NEXT: 2:       w2 = 1
+; CHECK-DUMP-NEXT: 3:       *(u32 *)(r1 + 0) = w2
+; CHECK-DUMP-NEXT: 4:       exit
+; CHECK-DUMP:      <bar>:
+; CHECK-DUMP-NEXT: 5:       r2 = 40
+; CHECK-DUMP-NEXT:          0000000000000028:  CO-RE <byte_off> [3] struct t::ub (0:1)
+; CHECK-DUMP-NEXT: 6:       r1 += r2
+; CHECK-DUMP-NEXT: 7:       w0 = *(u32 *)(r1 + 0)
+; CHECK-DUMP-NEXT: 8:       exit
+
+; Function Attrs: nofree nosync nounwind memory(none)
+declare ptr @llvm.bpf.passthrough.p0.p0(i32, ptr) #2
+
+attributes #0 = { "btf_ama" }
+attributes #1 = { nofree nounwind memory(readwrite, target_mem0: none, target_mem1: none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="v3" }
+attributes #2 = { nofree nosync nounwind memory(none) }
+
+!llvm.dbg.cu = !{!10}
+!llvm.module.flags = !{!11, !12, !13, !14}
+!llvm.ident = !{!15}
+!llvm.errno.tbaa = !{!16}
+
+!0 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !1, line: 1, size: 352, elements: !2)
+!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/tmp", checksumkind: CSK_MD5, checksum: "c0b1e83c4a0097ba80a1a5b0da78cb75")
+!2 = !{!3, !8}
+!3 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !0, file: !1, line: 2, baseType: !4, size: 320)
+!4 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 320, elements: !6)
+!5 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!6 = !{!7}
+!7 = !DISubrange(count: 40)
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "ub", scope: !0, file: !1, line: 3, baseType: !9, size: 32, offset: 320)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 23.0.0git (https://github.com/llvm/llvm-project.git 11727c11f833873af97d3969483f488e5251f35d)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!11 = !{i32 7, !"Dwarf Version", i32 5}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+!13 = !{i32 7, !"frame-pointer", i32 2}
+!14 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!15 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git 11727c11f833873af97d3969483f488e5251f35d)"}
+!16 = !{!17, !17, i64 0}
+!17 = !{!"int", !18, i64 0}
+!18 = !{!"omnipotent char", !19, i64 0}
+!19 = !{!"Simple C/C++ TBAA"}
+!20 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 5, type: !21, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !10, retainedNodes: !25, keyInstructions: true)
+!21 = !DISubroutineType(types: !22)
+!22 = !{null, !23}
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64)
+!24 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !0)
+!25 = !{!26}
+!26 = !DILocalVariable(name: "t", arg: 1, scope: !20, file: !1, line: 5, type: !23)
+!27 = !DILocation(line: 0, scope: !20)
+!28 = !DILocation(line: 6, column: 9, scope: !20, atomGroup: 1, atomRank: 1)
+!29 = !{!30, !17, i64 40}
+!30 = !{!"t", !18, i64 0, !17, i64 40}
+!31 = !DILocation(line: 7, column: 1, scope: !20, atomGroup: 2, atomRank: 1)
+!32 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !33, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !10, retainedNodes: !35, keyInstructions: true)
+!33 = !DISubroutineType(types: !34)
+!34 = !{!9, !23}
+!35 = !{!36}
+!36 = !DILocalVariable(name: "t", arg: 1, scope: !32, file: !1, line: 8, type: !23)
+!37 = !DILocation(line: 0, scope: !32)
+!38 = !DILocation(line: 9, column: 13, scope: !32, atomGroup: 1, atomRank: 2)
+!39 = !DILocation(line: 9, column: 3, scope: !32, atomGroup: 1, atomRank: 1)



More information about the llvm-commits mailing list