xref: /llvm-project/llvm/test/Instrumentation/DataFlowSanitizer/load.ll (revision ecb85b5cd89f9797c538675ee3ab93e350c57bd5)
1; RUN: opt < %s -passes=dfsan -dfsan-combine-pointer-labels-on-load=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_LOAD_PTR
2; RUN: opt < %s -passes=dfsan -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
4target triple = "x86_64-unknown-linux-gnu"
5
6; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
7; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
8
9define {} @load0(ptr %p) {
10  ; CHECK-LABEL:           @load0.dfsan
11  ; CHECK-NEXT:            %a = load {}, ptr %p, align 1
12  ; CHECK-NEXT:            store {} zeroinitializer, ptr @__dfsan_retval_tls, align [[ALIGN:2]]
13  ; CHECK-NEXT:            ret {} %a
14
15  %a = load {}, ptr %p
16  ret {} %a
17}
18
19define i8 @load8(ptr %p) {
20  ; CHECK-LABEL:           @load8.dfsan
21  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
22  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
23  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]
24  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
25  ; CHECK-NEXT:            %[[#SHADOW:]] = load i8, ptr %[[#SHADOW_PTR]]
26  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
27  ; CHECK-NEXT:            %a = load i8, ptr %p
28  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
29  ; CHECK-NEXT:            ret i8 %a
30
31  %a = load i8, ptr %p
32  ret i8 %a
33}
34
35define i16 @load16(ptr %p) {
36  ; CHECK-LABEL:           @load16.dfsan
37  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
38  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
39  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
40  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
41  ; CHECK-NEXT:            %[[#SHADOW_PTR+1]] = getelementptr i8, ptr %[[#SHADOW_PTR]], i64 1
42  ; CHECK-NEXT:            %[[#SHADOW:]]  = load i8, ptr %[[#SHADOW_PTR]]
43  ; CHECK-NEXT:            %[[#SHADOW+1]] = load i8, ptr %[[#SHADOW_PTR+1]]
44
45  ; CHECK-NEXT:            %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#SHADOW+1]]
46  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
47  ; CHECK-NEXT:            %a = load i16, ptr %p
48  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
49  ; CHECK-NEXT:            ret i16 %a
50
51  %a = load i16, ptr %p
52  ret i16 %a
53}
54
55define i32 @load32(ptr %p) {
56  ; CHECK-LABEL:           @load32.dfsan
57  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
58  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
59  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
60  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
61  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = load i[[#WSBITS:32]], ptr %[[#SHADOW_PTR]], align 1
62  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW]], 16
63  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i[[#WSBITS]] %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
64  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW]], 8
65  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i[[#WSBITS]] %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
66  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i[[#WSBITS]] %[[#WIDE_SHADOW]] to i8
67  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
68  ; CHECK-NEXT:            %a = load i32, ptr %p, align 4
69  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
70  ; CHECK-NEXT:            ret i32 %a
71
72  %a = load i32, ptr %p
73  ret i32 %a
74}
75
76define i64 @load64(ptr %p) {
77  ; CHECK-LABEL:           @load64.dfsan
78  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
79  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
80  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
81  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
82  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = load i64, ptr %[[#SHADOW_PTR]], align 1
83  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
84  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
85  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
86  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
87  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
88  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
89  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i8
90  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
91  ; CHECK-NEXT:            %a = load i64, ptr %p, align 8
92  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
93  ; CHECK-NEXT:            ret i64 %a
94
95  %a = load i64, ptr %p
96  ret i64 %a
97}
98
99define i128 @load128(ptr %p) {
100  ; CHECK-LABEL:           @load128.dfsan
101  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
102  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
103  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
104  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
105  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = load i64, ptr %[[#SHADOW_PTR]], align 1
106  ; CHECK-NEXT:            %[[#WIDE_SHADOW_PTR2:]] = getelementptr i64, ptr %[[#SHADOW_PTR]], i64 1
107  ; CHECK-NEXT:            %[[#WIDE_SHADOW2:]] = load i64, ptr %[[#WIDE_SHADOW_PTR2]], align 1
108  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW2]]
109  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
110  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
111  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
112  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
113  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
114  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
115  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i8
116  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
117  ; CHECK-NEXT:            %a = load i128, ptr %p, align 8
118  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
119  ; CHECK-NEXT:            ret i128 %a
120
121  %a = load i128, ptr %p
122  ret i128 %a
123}
124
125
126define i17 @load17(ptr %p) {
127  ; CHECK-LABEL:           @load17.dfsan
128  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
129  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
130  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
131  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
132  ; CHECK-NEXT:            %[[#SHADOW:]] = call zeroext i8 @__dfsan_union_load(ptr %[[#SHADOW_PTR]], i64 3)
133  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
134  ; CHECK-NEXT:            %a = load i17, ptr %p
135  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
136  ; CHECK-NEXT:            ret i17 %a
137
138  %a = load i17, ptr %p
139  ret i17 %a
140}
141
142@X = constant i1 1
143define i1 @load_global() {
144  ; CHECK-LABEL:           @load_global.dfsan
145  ; CHECK-NEXT:            %a = load i1, ptr @X
146  ; CHECK-NEXT:            store i8 0, ptr @__dfsan_retval_tls, align [[ALIGN]]
147  ; CHECK-NEXT:            ret i1 %a
148
149  %a = load i1, ptr @X
150  ret i1 %a
151}
152