Skip to content

Commit 00602ee

Browse files
committed
BPF: simplify IR generation for __builtin_btf_type_id()
This patch simplified IR generation for __builtin_btf_type_id(). For __builtin_btf_type_id(obj, flag), previously IR builtin looks like if (obj is a lvalue) llvm.bpf.btf.type.id(obj.ptr, 1, flag) !type else llvm.bpf.btf.type.id(obj, 0, flag) !type The purpose of the 2nd argument is to differentiate __builtin_btf_type_id(obj, flag) where obj is a lvalue vs. __builtin_btf_type_id(obj.ptr, flag) Note that obj or obj.ptr is never used by the backend and the `obj` argument is only used to derive the type. This code sequence is subject to potential llvm CSE when - obj is the same .e.g., nullptr - flag is the same - metadata type is different, e.g., typedef of struct "s" and strust "s". In the above, we don't want CSE since their metadata is different. This patch change IR builtin to llvm.bpf.btf.type.id(seq_num, flag) !type and seq_num is always increasing. This will prevent potential llvm CSE. Also report an error if the type name is empty for remote relocation since remote relocation needs non-empty type name to do relocation against vmlinux. Differential Revision: https://reviews.llvm.org/D85174
1 parent 4b25f67 commit 00602ee

File tree

5 files changed

+80
-123
lines changed

5 files changed

+80
-123
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 9 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10961,68 +10961,7 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
1096110961
{FieldAddr->getType()});
1096210962
return Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind});
1096310963
}
10964-
case BPF::BI__builtin_btf_type_id: {
10965-
Value *FieldVal = nullptr;
10966-
10967-
// The LValue cannot be converted Value in order to be used as the function
10968-
// parameter. If it is a structure, it is the "alloca" result of the LValue
10969-
// (a pointer) is used in the parameter. If it is a simple type,
10970-
// the value will be loaded from its corresponding "alloca" and used as
10971-
// the parameter. In our case, let us just get a pointer of the LValue
10972-
// since we do not really use the parameter. The purpose of parameter
10973-
// is to prevent the generated IR llvm.bpf.btf.type.id intrinsic call,
10974-
// which carries metadata, from being changed.
10975-
bool IsLValue = E->getArg(0)->isLValue();
10976-
if (IsLValue)
10977-
FieldVal = EmitLValue(E->getArg(0)).getPointer(*this);
10978-
else
10979-
FieldVal = EmitScalarExpr(E->getArg(0));
10980-
10981-
if (!getDebugInfo()) {
10982-
CGM.Error(E->getExprLoc(), "using __builtin_btf_type_id() without -g");
10983-
return nullptr;
10984-
}
10985-
10986-
// Generate debuginfo type for the first argument.
10987-
llvm::DIType *DbgInfo =
10988-
getDebugInfo()->getOrCreateStandaloneType(E->getArg(0)->getType(),
10989-
E->getArg(0)->getExprLoc());
10990-
10991-
ConstantInt *Flag = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
10992-
Value *FlagValue = ConstantInt::get(Int64Ty, Flag->getSExtValue());
10993-
10994-
// Built the IR for the btf_type_id intrinsic.
10995-
//
10996-
// In the above, we converted LValue argument to a pointer to LValue.
10997-
// For example, the following
10998-
// int v;
10999-
// C1: __builtin_btf_type_id(v, flag);
11000-
// will be converted to
11001-
// L1: llvm.bpf.btf.type.id(&v, flag)
11002-
// This makes it hard to differentiate from
11003-
// C2: __builtin_btf_type_id(&v, flag);
11004-
// to
11005-
// L2: llvm.bpf.btf.type.id(&v, flag)
11006-
//
11007-
// If both C1 and C2 are present in the code, the llvm may later
11008-
// on do CSE on L1 and L2, which will result in incorrect tagged types.
11009-
//
11010-
// The C1->L1 transformation only happens if the argument of
11011-
// __builtin_btf_type_id() is a LValue. So Let us put whether
11012-
// the argument is an LValue or not into generated IR. This should
11013-
// prevent potential CSE from causing debuginfo type loss.
11014-
//
11015-
// The generated IR intrinsics will hence look like
11016-
// L1: llvm.bpf.btf.type.id(&v, 1, flag) !di_type_for_{v};
11017-
// L2: llvm.bpf.btf.type.id(&v, 0, flag) !di_type_for_{&v};
11018-
Constant *CV = ConstantInt::get(IntTy, IsLValue);
11019-
llvm::Function *FnBtfTypeId = llvm::Intrinsic::getDeclaration(
11020-
&CGM.getModule(), llvm::Intrinsic::bpf_btf_type_id,
11021-
{FieldVal->getType(), CV->getType()});
11022-
CallInst *Fn = Builder.CreateCall(FnBtfTypeId, {FieldVal, CV, FlagValue});
11023-
Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
11024-
return Fn;
11025-
}
10964+
case BPF::BI__builtin_btf_type_id:
1102610965
case BPF::BI__builtin_preserve_type_info: {
1102710966
if (!getDebugInfo()) {
1102810967
CGM.Error(E->getExprLoc(), "using builtin function without -g");
@@ -11037,10 +10976,14 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
1103710976
Value *FlagValue = ConstantInt::get(Int64Ty, Flag->getSExtValue());
1103810977
Value *SeqNumVal = ConstantInt::get(Int32Ty, BuiltinSeqNum++);
1103910978

11040-
llvm::Function *FnPreserveTypeInfo = llvm::Intrinsic::getDeclaration(
11041-
&CGM.getModule(), llvm::Intrinsic::bpf_preserve_type_info, {});
11042-
CallInst *Fn =
11043-
Builder.CreateCall(FnPreserveTypeInfo, {SeqNumVal, FlagValue});
10979+
llvm::Function *FnDecl;
10980+
if (BuiltinID == BPF::BI__builtin_btf_type_id)
10981+
FnDecl = llvm::Intrinsic::getDeclaration(
10982+
&CGM.getModule(), llvm::Intrinsic::bpf_btf_type_id, {});
10983+
else
10984+
FnDecl = llvm::Intrinsic::getDeclaration(
10985+
&CGM.getModule(), llvm::Intrinsic::bpf_preserve_type_info, {});
10986+
CallInst *Fn = Builder.CreateCall(FnDecl, {SeqNumVal, FlagValue});
1104410987
Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1104510988
return Fn;
1104610989
}

clang/test/CodeGen/builtin-bpf-btf-type-id.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,22 @@
44
unsigned test1(int a) { return __builtin_btf_type_id(a, 0); }
55
unsigned test2(int a) { return __builtin_btf_type_id(&a, 0); }
66

7+
struct t1 { int a; };
8+
typedef struct t1 __t1;
9+
unsigned test3() {
10+
return __builtin_btf_type_id(*(struct t1 *)0, 1) +
11+
__builtin_btf_type_id(*(__t1 *)0, 1);
12+
}
13+
714
// CHECK: define dso_local i32 @test1
8-
// CHECK: call i32 @llvm.bpf.btf.type.id.p0i32.i32(i32* %{{[0-9a-z.]+}}, i32 1, i64 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[INT:[0-9]+]]
15+
// CHECK: call i32 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[INT:[0-9]+]]
916
// CHECK: define dso_local i32 @test2
10-
// CHECK: call i32 @llvm.bpf.btf.type.id.p0i32.i32(i32* %{{[0-9a-z.]+}}, i32 0, i64 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[INT_POINTER:[0-9]+]]
17+
// CHECK: call i32 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[INT_POINTER:[0-9]+]]
18+
// CHECK: define dso_local i32 @test3
19+
// CHECK: call i32 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_T1:[0-9]+]]
20+
// CHECK: call i32 @llvm.bpf.btf.type.id(i32 3, i64 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[TYPEDEF_T1:[0-9]+]]
1121
//
1222
// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed
1323
// CHECK: ![[INT_POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[INT]], size: 64
24+
// CHECK: ![[TYPEDEF_T1]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__t1"
25+
// CHECK: ![[STRUCT_T1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1"

llvm/include/llvm/IR/IntrinsicsBPF.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
2424
Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i64_ty],
2525
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
2626
def int_bpf_btf_type_id : GCCBuiltin<"__builtin_bpf_btf_type_id">,
27-
Intrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_any_ty, llvm_i64_ty],
27+
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
2828
[IntrNoMem]>;
2929
def int_bpf_preserve_type_info : GCCBuiltin<"__builtin_bpf_preserve_type_info">,
3030
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],

llvm/lib/Target/BPF/BPFPreserveDIType.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,24 @@ bool BPFPreserveDIType::doTransformation(Module &M) {
9595
std::string BaseName = "llvm.btf_type_id.";
9696
int Count = 0;
9797
for (auto Call : PreserveDITypeCalls) {
98-
const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(2));
98+
const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
9999
assert(Flag);
100100
uint64_t FlagValue = Flag->getValue().getZExtValue();
101101

102102
if (FlagValue >= BPFCoreSharedInfo::MAX_BTF_TYPE_ID_FLAG)
103103
report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
104104

105+
MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
106+
105107
uint32_t Reloc;
106-
if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC)
108+
if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC) {
107109
Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL;
108-
else
110+
} else {
109111
Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE;
112+
DIType *Ty = cast<DIType>(MD);
113+
if (Ty->getName().empty())
114+
report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
115+
}
110116

111117
BasicBlock *BB = Call->getParent();
112118
IntegerType *VarType = Type::getInt32Ty(BB->getContext());
@@ -116,7 +122,6 @@ bool BPFPreserveDIType::doTransformation(Module &M) {
116122
new GlobalVariable(M, VarType, false, GlobalVariable::ExternalLinkage,
117123
NULL, GVName);
118124
GV->addAttribute(BPFCoreSharedInfo::TypeIdAttr);
119-
MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
120125
GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
121126

122127
// Load the global variable which represents the type info.

llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,90 +13,87 @@
1313
; bpf_log(__builtin_btf_type_id(tmp__abc, 0), &tmp__abc, sizeof(tmp__abc));
1414
; }
1515
; void prog2() {
16-
; bpf_log(__builtin_btf_type_id(&tmp__abc, 1), &tmp__abc, sizeof(tmp__abc));
16+
; bpf_log(__builtin_btf_type_id(&tmp__abc, 0), &tmp__abc, sizeof(tmp__abc));
1717
; }
1818
; void prog3() {
1919
; bpf_log(__builtin_btf_type_id(tmp__abc.f1[3], 1), &tmp__abc, sizeof(tmp__abc));
2020
; }
2121
; Compilation flag:
2222
; clang -target bpf -O2 -g -S -emit-llvm test.c
2323

24-
%struct.anon = type { [100 x i8], i32 }
25-
2624
@tmp__abc = dso_local global { <{ i8, i8, [98 x i8] }>, i32 } { <{ i8, i8, [98 x i8] }> <{ i8 1, i8 3, [98 x i8] zeroinitializer }>, i32 0 }, align 4, !dbg !0
2725

2826
; Function Attrs: nounwind
2927
define dso_local void @prog1() local_unnamed_addr #0 !dbg !28 {
3028
entry:
31-
%0 = tail call i32 @llvm.bpf.btf.type.id.p0s_struct.anons.i32(%struct.anon* bitcast ({ <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc to %struct.anon*), i32 1, i64 0), !dbg !31, !llvm.preserve.access.index !7
29+
%0 = tail call i32 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !31, !llvm.preserve.access.index !7
3230
%call = tail call i32 inttoptr (i64 999 to i32 (i32, i8*, i32)*)(i32 %0, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i64 0, i32 0, i32 0), i32 104) #2, !dbg !32
3331
ret void, !dbg !33
3432
}
3533

3634
; Function Attrs: nounwind readnone
37-
declare i32 @llvm.bpf.btf.type.id.p0s_struct.anons.i32(%struct.anon*, i32, i64) #1
35+
declare i32 @llvm.bpf.btf.type.id(i32, i64) #1
3836

3937
; Function Attrs: nounwind
4038
define dso_local void @prog2() local_unnamed_addr #0 !dbg !34 {
4139
entry:
42-
%0 = tail call i32 @llvm.bpf.btf.type.id.p0s_struct.anons.i32(%struct.anon* bitcast ({ <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc to %struct.anon*), i32 0, i64 1), !dbg !35, !llvm.preserve.access.index !6
40+
%0 = tail call i32 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !35, !llvm.preserve.access.index !6
4341
%call = tail call i32 inttoptr (i64 999 to i32 (i32, i8*, i32)*)(i32 %0, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i64 0, i32 0, i32 0), i32 104) #2, !dbg !36
4442
ret void, !dbg !37
4543
}
4644

4745
; Function Attrs: nounwind
4846
define dso_local void @prog3() local_unnamed_addr #0 !dbg !38 {
4947
entry:
50-
%0 = tail call i32 @llvm.bpf.btf.type.id.p0i8.i32(i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i64 0, i32 0, i32 2, i64 1), i32 1, i64 1), !dbg !39, !llvm.preserve.access.index !11
48+
%0 = tail call i32 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !39, !llvm.preserve.access.index !11
5149
%call = tail call i32 inttoptr (i64 999 to i32 (i32, i8*, i32)*)(i32 %0, i8* getelementptr inbounds ({ <{ i8, i8, [98 x i8] }>, i32 }, { <{ i8, i8, [98 x i8] }>, i32 }* @tmp__abc, i64 0, i32 0, i32 0), i32 104) #2, !dbg !40
5250
ret void, !dbg !41
5351
}
5452

55-
; CHECK-LABEL: prog1
56-
; CHECK: r1 = 3
57-
; CHECK-LABEL: prog2
58-
; CHECK: r1 = 10
59-
; CHECK-LABEL: prog3
60-
; CHECK: r1 = 4
61-
;
62-
; CHECK: .long 0 # BTF_KIND_STRUCT(id = 3)
63-
; CHECK-NEXT: .long 67108866 # 0x4000002
64-
; CHECK-NEXT: .long 104
65-
; CHECK-NEXT: .long 13
66-
; CHECK-NEXT: .long 5
67-
; CHECK-NEXT: .long 0 # 0x0
68-
; CHECK-NEXT: .long 16
69-
; CHECK-NEXT: .long 7
70-
; CHECK-NEXT: .long 800 # 0x320
71-
; CHECK-NEXT: .long 19 # BTF_KIND_INT(id = 4)
72-
; CHECK-NEXT: .long 16777216 # 0x1000000
73-
; CHECK-NEXT: .long 1
74-
; CHECK-NEXT: .long 16777224 # 0x1000008
75-
; CHECK: .long 0 # BTF_KIND_PTR(id = 10)
76-
; CHECK-NEXT: .long 33554432 # 0x2000000
77-
; CHECK-NEXT: .long 3
53+
; CHECK-LABEL: prog1
54+
; CHECK: r1 = 3
55+
; CHECK-LABEL: prog2
56+
; CHECK: r1 = 10
57+
; CHECK-LABEL: prog3
58+
; CHECK: r1 = 4
7859

79-
; CHECK: .long 16 # FieldReloc
80-
; CHECK-NEXT: .long {{[0-9]+}} # Field reloc section string offset={{[0-9]+}}
81-
; CHECK-NEXT: .long 3
82-
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
83-
; CHECK-NEXT: .long 3
84-
; CHECK-NEXT: .long {{[0-9]+}}
85-
; CHECK-NEXT: .long 6
86-
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
87-
; CHECK-NEXT: .long 10
88-
; CHECK-NEXT: .long {{[0-9]+}}
89-
; CHECK-NEXT: .long 7
90-
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
91-
; CHECK-NEXT: .long 4
92-
; CHECK-NEXT: .long {{[0-9]+}}
93-
; CHECK-NEXT: .long 7
60+
; CHECK: .long 0 # BTF_KIND_STRUCT(id = 3)
61+
; CHECK-NEXT: .long 67108866 # 0x4000002
62+
; CHECK-NEXT: .long 104
63+
; CHECK-NEXT: .long 13
64+
; CHECK-NEXT: .long 5
65+
; CHECK-NEXT: .long 0 # 0x0
66+
; CHECK-NEXT: .long 16
67+
; CHECK-NEXT: .long 7
68+
; CHECK-NEXT: .long 800 # 0x320
69+
; CHECK: .long 19 # BTF_KIND_INT(id = 4)
70+
; CHECK: .long 0 # BTF_KIND_PTR(id = 10)
71+
; CHECK-NEXT: .long 33554432 # 0x2000000
72+
; CHECK-NEXT: .long 3
9473

74+
; CHECK: .ascii ".text" # string offset=7
75+
; CHECK: .ascii "f1" # string offset=13
76+
; CHECK: .ascii "f2" # string offset=16
77+
; CHECK: .ascii "char" # string offset=19
78+
; CHECK: .byte 48 # string offset=48
9579

96-
; Function Attrs: nounwind readnone
97-
declare i32 @llvm.bpf.btf.type.id.p0i8.i32(i8*, i32, i64) #1
80+
; CHECK: .long 16 # FieldReloc
81+
; CHECK-NEXT: .long 7 # Field reloc section string offset=7
82+
; CHECK-NEXT: .long 3
83+
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
84+
; CHECK-NEXT: .long 3
85+
; CHECK-NEXT: .long 48
86+
; CHECK-NEXT: .long 6
87+
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
88+
; CHECK-NEXT: .long 10
89+
; CHECK-NEXT: .long 48
90+
; CHECK-NEXT: .long 6
91+
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}
92+
; CHECK-NEXT: .long 4
93+
; CHECK-NEXT: .long 48
94+
; CHECK-NEXT: .long 7
9895

99-
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" }
96+
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"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
10097
attributes #1 = { nounwind readnone }
10198
attributes #2 = { nounwind }
10299

@@ -106,7 +103,7 @@ attributes #2 = { nounwind }
106103

107104
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
108105
!1 = distinct !DIGlobalVariable(name: "tmp__abc", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true)
109-
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 95253d8f16b8085b4b85cb3a6106ccbfe8a6d9b2)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !16, splitDebugInlining: false, nameTableKind: None)
106+
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git f39aae11dca3f8f8c2c755a871726ed2fa82fd57)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !16, splitDebugInlining: false, nameTableKind: None)
110107
!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core")
111108
!4 = !{}
112109
!5 = !{!6, !11}
@@ -131,7 +128,7 @@ attributes #2 = { nounwind }
131128
!24 = !{i32 7, !"Dwarf Version", i32 4}
132129
!25 = !{i32 2, !"Debug Info Version", i32 3}
133130
!26 = !{i32 1, !"wchar_size", i32 4}
134-
!27 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 95253d8f16b8085b4b85cb3a6106ccbfe8a6d9b2)"}
131+
!27 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git f39aae11dca3f8f8c2c755a871726ed2fa82fd57)"}
135132
!28 = distinct !DISubprogram(name: "prog1", scope: !3, file: !3, line: 6, type: !29, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
136133
!29 = !DISubroutineType(types: !30)
137134
!30 = !{null}

0 commit comments

Comments
 (0)