Skip to content

Commit

Permalink
Consistently store pid, tid and probe id as int32_t
Browse files Browse the repository at this point in the history
Previously, they were mostly 64-bit but had a few places where they were
treated as 32-bit.

This saves some memory and may marginally improve performance when
pushing usyms onto the ring buffer, etc., but it's mainly just a nice
little clean up for consistency. Maybe it even eliminates some
undiscovered lurking bugs.
  • Loading branch information
ajor committed Oct 4, 2024
1 parent b29d36a commit 5746676
Show file tree
Hide file tree
Showing 36 changed files with 455 additions and 395 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to

## Unreleased

#### Breaking Changes
- Return `uint32` instead of `uint64` for `pid` and `tid` builtins
- [#3441](https://github.com/bpftrace/bpftrace/pull/3441)
#### Added
- Add `--dry-run` CLI option
- [#3203](https://github.com/bpftrace/bpftrace/pull/3203)
Expand Down
4 changes: 2 additions & 2 deletions man/adoc/bpftrace.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ For string arguments use the `str()` call to retrieve the value.
| ID of the NUMA node executing the BPF program

| pid
| uint64
| uint32
| 4.2
| get_current_pid_tgid
| Process ID of the current thread (aka thread group ID), as seen from the init namespace
Expand Down Expand Up @@ -1134,7 +1134,7 @@ For string arguments use the `str()` call to retrieve the value.
| Value returned by the function being traced (kretprobe, uretprobe, kretfunc)

| tid
| uint64
| uint32
| 4.2
| get_current_pid_tgid
| Thread ID of the current thread, as seen from the init namespace
Expand Down
12 changes: 6 additions & 6 deletions src/ast/irbuilderbpf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ libbpf::bpf_func_id IRBuilderBPF::selectProbeReadHelper(AddrSpace as, bool str)
Value *IRBuilderBPF::CreateGetPid(const location &loc)
{
Value *pidtgid = CreateGetPidTgid(loc);
Value *pid = CreateLShr(pidtgid, 32, "pid");
Value *pid = CreateTrunc(CreateLShr(pidtgid, 32), getInt32Ty(), "pid");
return pid;
}

Value *IRBuilderBPF::CreateGetTid(const location &loc)
{
Value *pidtgid = CreateGetPidTgid(loc);
Value *tid = CreateAnd(pidtgid, 0xffffffff, "tid");
Value *tid = CreateTrunc(pidtgid, getInt32Ty(), "tid");
return tid;
}

Expand All @@ -93,15 +93,15 @@ AllocaInst *IRBuilderBPF::CreateUSym(llvm::Value *val,
{
std::vector<llvm::Type *> elements = {
getInt64Ty(), // addr
getInt64Ty(), // pid
getInt64Ty(), // probe id
getInt32Ty(), // pid
getInt32Ty(), // probe id
};
StructType *usym_t = GetStructType("usym_t", elements, false);
AllocaInst *buf = CreateAllocaBPF(usym_t, "usym");

Value *pid = CreateGetPid(loc);
Value *probe_id_val = Constant::getIntegerValue(getInt64Ty(),
APInt(64, probe_id));
Value *probe_id_val = Constant::getIntegerValue(getInt32Ty(),
APInt(32, probe_id));

// The extra 0 here ensures the type of addr_offset will be int64
Value *addr_offset = CreateGEP(usym_t, buf, { getInt64(0), getInt32(0) });
Expand Down
3 changes: 2 additions & 1 deletion src/ast/passes/semantic_analyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,9 @@ void SemanticAnalyser::visit(Builtin &builtin)
LOG(ERROR, builtin.loc, err_) << "invalid program type";
break;
}
} else if (builtin.ident == "pid" || builtin.ident == "tid") {
builtin.type = CreateUInt32();
} else if (builtin.ident == "nsecs" || builtin.ident == "elapsed" ||
builtin.ident == "pid" || builtin.ident == "tid" ||
builtin.ident == "cgroup" || builtin.ident == "uid" ||
builtin.ident == "gid" || builtin.ident == "cpu" ||
builtin.ident == "rand" || builtin.ident == "numaid" ||
Expand Down
12 changes: 6 additions & 6 deletions src/bpftrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,8 @@ std::vector<std::unique_ptr<IPrintable>> BPFtrace::get_arg_values(
case Type::usym_t:
arg_values.push_back(std::make_unique<PrintableString>(resolve_usym(
*reinterpret_cast<uint64_t *>(arg_data + arg.offset),
*reinterpret_cast<uint64_t *>(arg_data + arg.offset + 8),
*reinterpret_cast<uint64_t *>(arg_data + arg.offset + 16))));
*reinterpret_cast<int32_t *>(arg_data + arg.offset + 8),
*reinterpret_cast<int32_t *>(arg_data + arg.offset + 12))));
break;
case Type::inet:
arg_values.push_back(std::make_unique<PrintableString>(resolve_inet(
Expand Down Expand Up @@ -1545,8 +1545,8 @@ std::optional<std::vector<uint8_t>> BPFtrace::find_empty_key(

std::string BPFtrace::get_stack(int64_t stackid,
uint32_t nr_stack_frames,
int pid,
int probe_id,
int32_t pid,
int32_t probe_id,
bool ustack,
StackType stack_type,
int indent)
Expand Down Expand Up @@ -1826,8 +1826,8 @@ std::string BPFtrace::resolve_inet(int af, const uint8_t *inet) const
}

std::string BPFtrace::resolve_usym(uint64_t addr,
int pid,
int probe_id,
int32_t pid,
int32_t probe_id,
bool show_offset,
bool show_module)
{
Expand Down
8 changes: 4 additions & 4 deletions src/bpftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,16 @@ class BPFtrace {
int print_map(const BpfMap &map, uint32_t top, uint32_t div);
std::string get_stack(int64_t stackid,
uint32_t nr_stack_frames,
int pid,
int probe_id,
int32_t pid,
int32_t probe_id,
bool ustack,
StackType stack_type,
int indent = 0);
std::string resolve_buf(const char *buf, size_t size);
std::string resolve_ksym(uint64_t addr, bool show_offset = false);
std::string resolve_usym(uint64_t addr,
int pid,
int probe_id,
int32_t pid,
int32_t probe_id,
bool show_offset = false,
bool show_module = false);
std::string resolve_inet(int af, const uint8_t *inet) const;
Expand Down
8 changes: 4 additions & 4 deletions src/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ std::string Output::value_to_str(BPFtrace &bpftrace,
8);
}
case Type::ksym_t: {
return bpftrace.resolve_ksym(read_data<uintptr_t>(value.data()));
return bpftrace.resolve_ksym(read_data<uint64_t>(value.data()));
}
case Type::usym_t: {
return bpftrace.resolve_usym(read_data<uintptr_t>(value.data()),
read_data<uintptr_t>(value.data() + 8),
read_data<uint64_t>(value.data() + 16));
return bpftrace.resolve_usym(read_data<uint64_t>(value.data()),
read_data<uint32_t>(value.data() + 8),
read_data<uint32_t>(value.data() + 12));
}
case Type::inet: {
return bpftrace.resolve_inet(read_data<uint64_t>(value.data()),
Expand Down
2 changes: 1 addition & 1 deletion src/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ SizedType CreateHist()

SizedType CreateUSym()
{
return SizedType(Type::usym_t, 24);
return SizedType(Type::usym_t, 16);
}

SizedType CreateKSym()
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/cast_int_to_arr.cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace codegen {

TEST(codegen, cast_int_to_arr)
{
test("kprobe:f { $a=(uint8[8])pid; @ = $a[0]; }", NAME);
test("kprobe:f { $a=(uint8[8])0; @ = $a[0]; }", NAME);
}

} // namespace codegen
Expand Down
21 changes: 11 additions & 10 deletions tests/codegen/llvm/builtin_func_uprobe.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target triple = "bpf-pc-linux"
%"struct map_t" = type { ptr, ptr, ptr, ptr }
%"struct map_t.0" = type { ptr, ptr }
%"struct map_t.1" = type { ptr, ptr, ptr, ptr }
%usym_t = type { i64, i64, i64 }
%usym_t = type { i64, i32, i32 }

@LICENSE = global [4 x i8] c"GPL\00", section "license"
@AT_x = dso_local global %"struct map_t" zeroinitializer, section ".maps", !dbg !0
Expand All @@ -24,13 +24,14 @@ entry:
%func = load volatile i64, ptr %1, align 8
call void @llvm.lifetime.start.p0(i64 -1, ptr %usym)
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
%2 = getelementptr %usym_t, ptr %usym, i64 0, i32 0
%3 = getelementptr %usym_t, ptr %usym, i64 0, i32 1
%4 = getelementptr %usym_t, ptr %usym, i64 0, i32 2
store i64 %func, ptr %2, align 8
store i64 %pid, ptr %3, align 8
store i64 0, ptr %4, align 8
%2 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %2 to i32
%3 = getelementptr %usym_t, ptr %usym, i64 0, i32 0
%4 = getelementptr %usym_t, ptr %usym, i64 0, i32 1
%5 = getelementptr %usym_t, ptr %usym, i64 0, i32 2
store i64 %func, ptr %3, align 8
store i32 %pid, ptr %4, align 4
store i32 0, ptr %5, align 4
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %usym, i64 0)
Expand Down Expand Up @@ -72,10 +73,10 @@ attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: re
!18 = !DIBasicType(name: "int32", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !20, size: 64, offset: 192)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 64)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 192, elements: !23)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 128, elements: !23)
!22 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!23 = !{!24}
!24 = !DISubrange(count: 24, lowerBound: 0)
!24 = !DISubrange(count: 16, lowerBound: 0)
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !27, isLocal: false, isDefinition: true)
!27 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !28)
Expand Down
21 changes: 11 additions & 10 deletions tests/codegen/llvm/builtin_func_uretprobe.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target triple = "bpf-pc-linux"
%"struct map_t" = type { ptr, ptr, ptr, ptr }
%"struct map_t.0" = type { ptr, ptr }
%"struct map_t.1" = type { ptr, ptr, ptr, ptr }
%usym_t = type { i64, i64, i64 }
%usym_t = type { i64, i32, i32 }

@LICENSE = global [4 x i8] c"GPL\00", section "license"
@AT_x = dso_local global %"struct map_t" zeroinitializer, section ".maps", !dbg !0
Expand All @@ -23,13 +23,14 @@ entry:
%get_func_ip = call i64 inttoptr (i64 173 to ptr)(ptr %0)
call void @llvm.lifetime.start.p0(i64 -1, ptr %usym)
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
%1 = getelementptr %usym_t, ptr %usym, i64 0, i32 0
%2 = getelementptr %usym_t, ptr %usym, i64 0, i32 1
%3 = getelementptr %usym_t, ptr %usym, i64 0, i32 2
store i64 %get_func_ip, ptr %1, align 8
store i64 %pid, ptr %2, align 8
store i64 0, ptr %3, align 8
%1 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %1 to i32
%2 = getelementptr %usym_t, ptr %usym, i64 0, i32 0
%3 = getelementptr %usym_t, ptr %usym, i64 0, i32 1
%4 = getelementptr %usym_t, ptr %usym, i64 0, i32 2
store i64 %get_func_ip, ptr %2, align 8
store i32 %pid, ptr %3, align 4
store i32 0, ptr %4, align 4
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %usym, i64 0)
Expand Down Expand Up @@ -71,10 +72,10 @@ attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: re
!18 = !DIBasicType(name: "int32", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !20, size: 64, offset: 192)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 64)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 192, elements: !23)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 128, elements: !23)
!22 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!23 = !{!24}
!24 = !DISubrange(count: 24, lowerBound: 0)
!24 = !DISubrange(count: 16, lowerBound: 0)
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !27, isLocal: false, isDefinition: true)
!27 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !28)
Expand Down
11 changes: 7 additions & 4 deletions tests/codegen/llvm/builtin_pid_tid.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,23 @@ entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
%1 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %1 to i32
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
%2 = zext i32 %pid to i64
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_val")
store i64 %pid, ptr %"@x_val", align 8
store i64 %2, ptr %"@x_val", align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %"@x_val", i64 0)
call void @llvm.lifetime.end.p0(i64 -1, ptr %"@x_val")
call void @llvm.lifetime.end.p0(i64 -1, ptr %"@x_key")
%get_pid_tgid1 = call i64 inttoptr (i64 14 to ptr)()
%tid = and i64 %get_pid_tgid1, 4294967295
%tid = trunc i64 %get_pid_tgid1 to i32
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@y_key")
store i64 0, ptr %"@y_key", align 8
%3 = zext i32 %tid to i64
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@y_val")
store i64 %tid, ptr %"@y_val", align 8
store i64 %3, ptr %"@y_val", align 8
%update_elem2 = call i64 inttoptr (i64 2 to ptr)(ptr @AT_y, ptr %"@y_key", ptr %"@y_val", i64 0)
call void @llvm.lifetime.end.p0(i64 -1, ptr %"@y_val")
call void @llvm.lifetime.end.p0(i64 -1, ptr %"@y_key")
Expand Down
27 changes: 14 additions & 13 deletions tests/codegen/llvm/builtin_ustack.ll
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ merge_block: ; preds = %stack_scratch_failu
store i32 %8, ptr %7, align 4
%9 = getelementptr %stack_t, ptr %stack_args, i64 0, i32 2
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
store i64 %pid, ptr %9, align 8
%10 = getelementptr %stack_t, ptr %stack_args, i64 0, i32 3
store i32 0, ptr %10, align 4
%10 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %10 to i32
store i32 %pid, ptr %9, align 4
%11 = getelementptr %stack_t, ptr %stack_args, i64 0, i32 3
store i32 0, ptr %11, align 4
call void @llvm.lifetime.end.p0(i64 -1, ptr %stack_key)
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
Expand All @@ -71,17 +72,17 @@ lookup_stack_scratch_failure: ; preds = %entry
lookup_stack_scratch_merge: ; preds = %entry
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %lookup_stack_scratch_map, i32 1016, ptr null)
%get_stack = call i32 inttoptr (i64 67 to ptr)(ptr %0, ptr %lookup_stack_scratch_map, i32 1016, i64 256)
%11 = icmp sge i32 %get_stack, 0
br i1 %11, label %get_stack_success, label %get_stack_fail
%12 = icmp sge i32 %get_stack, 0
br i1 %12, label %get_stack_success, label %get_stack_fail

get_stack_success: ; preds = %lookup_stack_scratch_merge
%12 = udiv i32 %get_stack, 8
%13 = getelementptr %stack_key, ptr %stack_key, i64 0, i32 1
store i32 %12, ptr %13, align 4
%14 = trunc i32 %12 to i8
%murmur_hash_2 = call i64 @murmur_hash_2(ptr %lookup_stack_scratch_map, i8 %14, i64 1)
%15 = getelementptr %stack_key, ptr %stack_key, i64 0, i32 0
store i64 %murmur_hash_2, ptr %15, align 8
%13 = udiv i32 %get_stack, 8
%14 = getelementptr %stack_key, ptr %stack_key, i64 0, i32 1
store i32 %13, ptr %14, align 4
%15 = trunc i32 %13 to i8
%murmur_hash_2 = call i64 @murmur_hash_2(ptr %lookup_stack_scratch_map, i8 %15, i64 1)
%16 = getelementptr %stack_key, ptr %stack_key, i64 0, i32 0
store i64 %murmur_hash_2, ptr %16, align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @stack_bpftrace_127, ptr %stack_key, ptr %lookup_stack_scratch_map, i64 0)
br label %merge_block

Expand Down
28 changes: 15 additions & 13 deletions tests/codegen/llvm/call_avg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,31 @@ entry:
store i64 0, ptr %"@x_key", align 8
%lookup_elem = call ptr inttoptr (i64 1 to ptr)(ptr @AT_x, ptr %"@x_key")
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
%1 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %1 to i32
%2 = zext i32 %pid to i64
%lookup_cond = icmp ne ptr %lookup_elem, null
br i1 %lookup_cond, label %lookup_success, label %lookup_failure

lookup_success: ; preds = %entry
%1 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 0
%2 = load i64, ptr %1, align 8
%3 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 1
%3 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 0
%4 = load i64, ptr %3, align 8
%5 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 0
%6 = add i64 %2, %pid
store i64 %6, ptr %5, align 8
%7 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 1
%8 = add i64 1, %4
%5 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 1
%6 = load i64, ptr %5, align 8
%7 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 0
%8 = add i64 %4, %2
store i64 %8, ptr %7, align 8
%9 = getelementptr %avg_stas_val, ptr %lookup_elem, i64 0, i32 1
%10 = add i64 1, %6
store i64 %10, ptr %9, align 8
br label %lookup_merge

lookup_failure: ; preds = %entry
call void @llvm.lifetime.start.p0(i64 -1, ptr %avg_struct)
%9 = getelementptr %avg_stas_val, ptr %avg_struct, i64 0, i32 0
store i64 %pid, ptr %9, align 8
%10 = getelementptr %avg_stas_val, ptr %avg_struct, i64 0, i32 1
store i64 1, ptr %10, align 8
%11 = getelementptr %avg_stas_val, ptr %avg_struct, i64 0, i32 0
store i64 %2, ptr %11, align 8
%12 = getelementptr %avg_stas_val, ptr %avg_struct, i64 0, i32 1
store i64 1, ptr %12, align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %avg_struct, i64 0)
call void @llvm.lifetime.end.p0(i64 -1, ptr %avg_struct)
br label %lookup_merge
Expand Down
12 changes: 7 additions & 5 deletions tests/codegen/llvm/call_hist.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ entry:
%lookup_elem_val = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%get_pid_tgid = call i64 inttoptr (i64 14 to ptr)()
%pid = lshr i64 %get_pid_tgid, 32
%log2 = call i64 @log2(i64 %pid, i64 0)
%1 = lshr i64 %get_pid_tgid, 32
%pid = trunc i64 %1 to i32
%2 = zext i32 %pid to i64
%log2 = call i64 @log2(i64 %2, i64 0)
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 %log2, ptr %"@x_key", align 8
%lookup_elem = call ptr inttoptr (i64 1 to ptr)(ptr @AT_x, ptr %"@x_key")
Expand All @@ -31,9 +33,9 @@ entry:
br i1 %map_lookup_cond, label %lookup_success, label %lookup_failure

lookup_success: ; preds = %entry
%1 = load i64, ptr %lookup_elem, align 8
%2 = add i64 %1, 1
store i64 %2, ptr %lookup_elem, align 8
%3 = load i64, ptr %lookup_elem, align 8
%4 = add i64 %3, 1
store i64 %4, ptr %lookup_elem, align 8
br label %lookup_merge

lookup_failure: ; preds = %entry
Expand Down
Loading

0 comments on commit 5746676

Please sign in to comment.