1; RUN: llc -march=bpfel -mattr=+alu32 < %s | FileCheck %s
2; Source:
3;   struct env_t {
4;     unsigned data;
5;     unsigned data_end;
6;   };
7;   extern int work(struct env_t *skb, unsigned offset);
8;   int test(struct env_t *skb)
9;   {
10;     void *cursor, *data_end;
11;     struct env_t *srh, *ip;
12;
13;     data_end = (void *)(long)skb->data_end;
14;     cursor = (void *)(long)skb->data;
15;
16;     ip = cursor; cursor += sizeof(*ip);
17;     if ((void *)ip + sizeof(*ip) > data_end)
18;       return 0;
19;
20;     srh = cursor; cursor += sizeof(*srh);
21;     if ((void *)srh + sizeof(*srh) > data_end)
22;       return 0;
23;
24;     return work(skb, (char *)srh - (char *)(long)skb->data);
25;   }
26; Compilation flag:
27;   clang -target bpf -O2 -emit-llvm -S test.c
28
29%struct.env_t = type { i32, i32 }
30
31; Function Attrs: nounwind
32define dso_local i32 @test(%struct.env_t* %skb) local_unnamed_addr #0 {
33entry:
34  %data_end1 = getelementptr inbounds %struct.env_t, %struct.env_t* %skb, i64 0, i32 1
35  %0 = load i32, i32* %data_end1, align 4, !tbaa !2
36  %conv = zext i32 %0 to i64
37  %1 = inttoptr i64 %conv to i8*
38  %data = getelementptr inbounds %struct.env_t, %struct.env_t* %skb, i64 0, i32 0
39  %2 = load i32, i32* %data, align 4, !tbaa !7
40  %conv2 = zext i32 %2 to i64
41  %3 = inttoptr i64 %conv2 to i8*
42  %add.ptr = getelementptr i8, i8* %3, i64 8
43  %cmp = icmp ugt i8* %add.ptr, %1
44  %add.ptr6 = getelementptr i8, i8* %3, i64 16
45  %cmp7 = icmp ugt i8* %add.ptr6, %1
46  %or.cond = or i1 %cmp, %cmp7
47  br i1 %or.cond, label %cleanup, label %if.end10
48
49if.end10:                                         ; preds = %entry
50  %sub.ptr.lhs.cast = ptrtoint i8* %add.ptr to i64
51  %4 = trunc i64 %sub.ptr.lhs.cast to i32
52  %conv13 = sub i32 %4, %2
53  %call = tail call i32 @work(%struct.env_t* nonnull %skb, i32 %conv13) #2
54  br label %cleanup
55
56cleanup:                                          ; preds = %entry, %if.end10
57  %retval.0 = phi i32 [ %call, %if.end10 ], [ 0, %entry ]
58  ret i32 %retval.0
59}
60
61; CHECK: w{{[0-9]+}} = *(u32 *)(r{{[0-9]+}} + 0)
62; CHECK-NOT: w{{[0-9]+}} = w{{[0-9]+}}
63
64declare dso_local i32 @work(%struct.env_t*, i32) local_unnamed_addr #1
65
66attributes #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" }
67attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="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" }
68attributes #2 = { nounwind }
69
70!llvm.module.flags = !{!0}
71!llvm.ident = !{!1}
72
73!0 = !{i32 1, !"wchar_size", i32 4}
74!1 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 016d3ce1f4b07ee3056f7c10fedb24c441c4870f)"}
75!2 = !{!3, !4, i64 4}
76!3 = !{!"env_t", !4, i64 0, !4, i64 4}
77!4 = !{!"int", !5, i64 0}
78!5 = !{!"omnipotent char", !6, i64 0}
79!6 = !{!"Simple C/C++ TBAA"}
80!7 = !{!3, !4, i64 0}
81