Skip to content

Commit 2455bf1

Browse files
r41k0uclaude
andcommitted
Tests: Add the integer-signedness C reference
Eight cases, each reading operands from .bss globals (so clang cannot fold) and writing its result to a .bss global (so the runtime proof is a bpftool map dump). The IR clang emits is the specification for the signedness work: s64 = u32 zext i32 -> i64 (widening is source-driven) u64 = s32 sext i32 -> i64 u32 / s32 udiv i32 (usual arithmetic conversions) u64 > s64 icmp ugt i64 u32 * u32 -> u64 mul i32, then zext (wraps at 32 before widening) u32 >> 4 lshr i32 s32 >> 4 ashr i32 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BSDVsZH5NtoASyxB8FCtGU
1 parent 526f113 commit 2455bf1

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

tests/c-form/signedness.bpf.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* Reference for integer signedness. Each case reads its operands from .bss
2+
* globals (so clang cannot constant-fold) and writes the result to a .bss
3+
* global (so the runtime proof is a `bpftool map dump`). The IR clang emits
4+
* for this file is the specification: zext vs sext on widening, udiv vs sdiv,
5+
* icmp ugt vs sgt, lshr vs ashr, and the trunc/zext pair that makes
6+
* u32 * u32 wrap at 32 bits. */
7+
#define SEC(name) __attribute__((section(name), used))
8+
typedef unsigned int __u32;
9+
typedef int __s32;
10+
typedef unsigned long long __u64;
11+
typedef long long __s64;
12+
13+
/* inputs */
14+
__u32 u32_max = 0xFFFFFFFFu;
15+
__s32 s32_neg = -1;
16+
__u32 u32_ten = 10;
17+
__s32 s32_neg2 = -2;
18+
__u64 u64_ten = 10;
19+
__s64 s64_neg = -1;
20+
__u32 u32_half = 0x80000000u;
21+
__u32 u32_two = 2;
22+
23+
/* results */
24+
__s64 widen_unsigned; /* s64 = u32 -> 4294967295 zext */
25+
__u64 widen_signed; /* u64 = s32 -> 0xffffffffffffffff sext */
26+
__s32 reinterpret; /* s32 = u32 -> -1 no-op */
27+
__u32 mixed_div; /* u32 / s32 -> 0 udiv i32 */
28+
__u64 unsigned_cmp; /* u64 > s64 -> 0 icmp ugt */
29+
__u64 narrow_wrap; /* u32 * u32 -> 0 (wraps at 32) trunc */
30+
__u32 shr_unsigned; /* u32 >> 4 -> 0x0FFFFFFF lshr */
31+
__s32 shr_signed; /* s32 >> 4 -> -1 ashr */
32+
33+
SEC("tracepoint/raw_syscalls/sys_enter")
34+
int prog(void *ctx)
35+
{
36+
widen_unsigned = u32_max;
37+
widen_signed = s32_neg;
38+
reinterpret = u32_max;
39+
mixed_div = u32_ten / s32_neg2;
40+
unsigned_cmp = u64_ten > s64_neg;
41+
narrow_wrap = u32_half * u32_two;
42+
shr_unsigned = u32_max >> 4;
43+
shr_signed = s32_neg >> 4;
44+
return 0;
45+
}
46+
47+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)