xref: /llvm-project/llvm/test/Instrumentation/DataFlowSanitizer/origin_load.ll (revision ecb85b5cd89f9797c538675ee3ab93e350c57bd5)
1; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,COMBINE_LOAD_PTR
2; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -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
6define {} @load0(ptr %p) {
7  ; CHECK-LABEL: @load0.dfsan
8  ; CHECK-NEXT: %a = load {}, ptr %p, align 1
9  ; CHECK-NEXT: store {} zeroinitializer, ptr @__dfsan_retval_tls, align [[ALIGN:2]]
10  ; CHECK-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 4
11  ; CHECK-NEXT: ret {} %a
12
13  %a = load {}, ptr %p
14  ret {} %a
15}
16
17define i16 @load_non_escaped_alloca() {
18  ; CHECK-LABEL: @load_non_escaped_alloca.dfsan
19  ; CHECK-NEXT: %[[#S_ALLOCA:]] = alloca i8, align 1
20  ; CHECK-NEXT: %_dfsa = alloca i32, align 4
21  ; CHECK:      %[[#SHADOW:]] = load i8, ptr %[[#S_ALLOCA]], align 1
22  ; CHECK-NEXT: %[[#ORIGIN:]] = load i32, ptr %_dfsa, align 4
23  ; CHECK-NEXT: %a = load i16, ptr %p, align 2
24  ; CHECK-NEXT: store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
25  ; CHECK-NEXT: store i32 %[[#ORIGIN]], ptr @__dfsan_retval_origin_tls, align 4
26
27  %p = alloca i16
28  %a = load i16, ptr %p
29  ret i16 %a
30}
31
32define ptr @load_escaped_alloca() {
33  ; CHECK-LABEL:  @load_escaped_alloca.dfsan
34  ; CHECK:        %[[#INTP:]] = ptrtoint ptr %p to i64
35  ; CHECK-NEXT:   %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#%.10d,MASK:]]
36  ; CHECK-NEXT:   %[[#SHADOW_PTR0:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
37  ; CHECK-NEXT:   %[[#ORIGIN_OFFSET:]] = add i64 %[[#SHADOW_OFFSET]], [[#%.10d,ORIGIN_BASE:]]
38  ; CHECK-NEXT:   %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
39  ; CHECK-NEXT:   %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
40  ; CHECK-NEXT:   {{%.*}} = load i32, ptr %[[#ORIGIN_PTR]], align 4
41  ; CHECK-NEXT:   %[[#SHADOW_PTR1:]] = getelementptr i8, ptr %[[#SHADOW_PTR0]], i64 1
42  ; CHECK-NEXT:   %[[#SHADOW:]]  = load i8, ptr %[[#SHADOW_PTR0]], align 1
43  ; CHECK-NEXT:   %[[#SHADOW+1]] = load i8, ptr %[[#SHADOW_PTR1]], align 1
44  ; CHECK-NEXT:   {{%.*}} = or i8 %[[#SHADOW]], %[[#SHADOW+1]]
45  ; CHECK-NEXT:   %a = load i16, ptr %p, align 2
46  ; CHECK-NEXT:   store i8 0, ptr @__dfsan_retval_tls, align [[ALIGN]]
47  ; CHECK-NEXT:   store i32 0, ptr @__dfsan_retval_origin_tls, align 4
48
49  %p = alloca i16
50  %a = load i16, ptr %p
51  ret ptr %p
52}
53
54@X = constant i1 1
55define i1 @load_global() {
56  ; CHECK-LABEL: @load_global.dfsan
57  ; CHECK: %a = load i1, ptr @X, align 1
58  ; CHECK-NEXT: store i8 0, ptr @__dfsan_retval_tls, align [[ALIGN]]
59  ; CHECK-NEXT: store i32 0, ptr @__dfsan_retval_origin_tls, align 4
60
61  %a = load i1, ptr @X
62  ret i1 %a
63}
64
65define i1 @load1(ptr %p) {
66  ; CHECK-LABEL:             @load1.dfsan
67
68  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
69  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
70
71  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
72  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
73  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
74  ; CHECK-NEXT:            %[[#ORIGIN_OFFSET:]] = add i64 %[[#SHADOW_OFFSET]], [[#ORIGIN_BASE]]
75  ; CHECK-NEXT:            %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
76  ; CHECK-NEXT:            %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
77  ; CHECK-NEXT:            %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 4
78  ; CHECK-NEXT:            %[[#AS:]] = load i8, ptr %[[#SHADOW_PTR]], align 1
79
80  ; COMBINE_LOAD_PTR-NEXT: %[[#AS:]] = or i8 %[[#AS]], %[[#PS]]
81  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
82  ; COMBINE_LOAD_PTR-NEXT: %[[#AO:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#AO]]
83
84  ; CHECK-NEXT:            %a = load i1, ptr %p, align 1
85  ; CHECK-NEXT:            store i8 %[[#AS]], ptr @__dfsan_retval_tls, align [[ALIGN]]
86  ; CHECK-NEXT:            store i32 %[[#AO]], ptr @__dfsan_retval_origin_tls, align 4
87
88  %a = load i1, ptr %p
89  ret i1 %a
90}
91
92define i16 @load16(i1 %i, ptr %p) {
93  ; CHECK-LABEL: @load16.dfsan
94
95  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr getelementptr inbounds ([200 x i32], ptr @__dfsan_arg_origin_tls, i64 0, i64 1), align 4
96  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
97
98  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
99  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
100  ; CHECK-NEXT:            %[[#SHADOW_PTR0:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
101  ; CHECK-NEXT:            %[[#ORIGIN_OFFSET:]] = add i64 %[[#SHADOW_OFFSET]], [[#ORIGIN_BASE]]
102  ; CHECK-NEXT:            %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
103  ; CHECK-NEXT:            %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
104  ; CHECK-NEXT:            %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 4
105  ; CHECK-NEXT:            %[[#SHADOW_PTR1:]] = getelementptr i8, ptr %[[#SHADOW_PTR0]], i64 1
106  ; CHECK-NEXT:            %[[#SHADOW:]]  = load i8, ptr %[[#SHADOW_PTR0]], align 1
107  ; CHECK-NEXT:            %[[#SHADOW+1]] = load i8, ptr %[[#SHADOW_PTR1]], align 1
108  ; CHECK-NEXT:            %[[#AS:]] = or i8 %[[#SHADOW]], %[[#SHADOW+1]]
109
110  ; COMBINE_LOAD_PTR-NEXT: %[[#AS:]] = or i8 %[[#AS]], %[[#PS]]
111  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
112  ; COMBINE_LOAD_PTR-NEXT: %[[#AO:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#AO]]
113
114  ; CHECK-NEXT:            %a = load i16, ptr %p, align 2
115  ; CHECK-NEXT:            store i8 %[[#AS]], ptr @__dfsan_retval_tls, align [[ALIGN]]
116  ; CHECK-NEXT:            store i32 %[[#AO]], ptr @__dfsan_retval_origin_tls, align 4
117
118  %a = load i16, ptr %p
119  ret i16 %a
120}
121
122define i32 @load32(ptr %p) {
123  ; CHECK-LABEL: @load32.dfsan
124
125  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
126  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
127
128  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
129  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
130  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
131  ; CHECK-NEXT:            %[[#ORIGIN_ADDR:]] = add i64 %[[#SHADOW_OFFSET]], [[#ORIGIN_BASE]]
132  ; CHECK-NEXT:            %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
133  ; CHECK-NEXT:            %[[#AO:]] = load i32, ptr %[[#ORIGIN_PTR]], align 4
134  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = load i[[#WSBITS:32]], ptr %[[#SHADOW_PTR]], align 1
135  ; CHECK-NEXT:            %[[#WIDE_SHADOW+1]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW]], 16
136  ; CHECK-NEXT:            %[[#WIDE_SHADOW+2]] = or i[[#WSBITS]] %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW+1]]
137  ; CHECK-NEXT:            %[[#WIDE_SHADOW+3]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW+2]], 8
138  ; CHECK-NEXT:            %[[#WIDE_SHADOW+4]] = or i[[#WSBITS]] %[[#WIDE_SHADOW+2]], %[[#WIDE_SHADOW+3]]
139  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i[[#WSBITS]] %[[#WIDE_SHADOW+4]] to i8
140
141  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
142  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
143  ; COMBINE_LOAD_PTR-NEXT: %[[#AO:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#AO]]
144
145  ; CHECK-NEXT:            %a = load i32, ptr %p, align 4
146  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
147  ; CHECK-NEXT:            store i32 %[[#AO]], ptr @__dfsan_retval_origin_tls, align 4
148
149  %a = load i32, ptr %p
150  ret i32 %a
151}
152
153define i64 @load64(ptr %p) {
154  ; CHECK-LABEL: @load64.dfsan
155
156  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
157  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
158
159  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
160  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
161  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
162  ; CHECK-NEXT:            %[[#ORIGIN_ADDR:]] = add i64 %[[#SHADOW_OFFSET]], [[#ORIGIN_BASE]]
163  ; CHECK-NEXT:            %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
164  ; CHECK-NEXT:            %[[#ORIGIN:]] = load i32, ptr %[[#ORIGIN_PTR]], align 8
165  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = load i64, ptr %[[#SHADOW_PTR]], align 1
166  ; CHECK-NEXT:            %[[#WIDE_SHADOW_LO:]] = shl i64 %[[#WIDE_SHADOW]], 32
167  ; CHECK-NEXT:            %[[#ORIGIN2_PTR:]] = getelementptr i32, ptr %[[#ORIGIN_PTR]], i64 1
168  ; CHECK-NEXT:            %[[#ORIGIN2:]] = load i32, ptr %[[#ORIGIN2_PTR]], align 8
169  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
170  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
171  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
172  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
173  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
174  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
175  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i8
176  ; CHECK-NEXT:            %[[#SHADOW_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW_LO]], 0
177  ; CHECK-NEXT:            %[[#ORIGIN:]] = select i1 %[[#SHADOW_NZ]], i32 %[[#ORIGIN]], i32 %[[#ORIGIN2]]
178  ; CHECK8-NEXT:           %[[#SHADOW_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW_LO]], 0
179  ; CHECK8-NEXT:           %[[#ORIGIN:]] = select i1 %[[#SHADOW_NZ]], i32 %[[#ORIGIN]], i32 %[[#ORIGIN2]]
180
181  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
182  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
183  ; COMBINE_LOAD_PTR-NEXT: %[[#ORIGIN:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#ORIGIN]]
184
185  ; CHECK-NEXT:            %a = load i64, ptr %p, align 8
186  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
187  ; CHECK-NEXT:            store i32 %[[#ORIGIN]], ptr @__dfsan_retval_origin_tls, align 4
188
189  %a = load i64, ptr %p
190  ret i64 %a
191}
192
193define i64 @load64_align2(ptr %p) {
194  ; CHECK-LABEL: @load64_align2.dfsan
195
196  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
197  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
198
199  ; CHECK-NEXT:            %[[#LABEL_ORIGIN:]] = call zeroext i64 @__dfsan_load_label_and_origin(ptr %p, i64 8)
200  ; CHECK-NEXT:            %[[#LABEL_ORIGIN+1]] = lshr i64 %[[#LABEL_ORIGIN]], 32
201  ; CHECK-NEXT:            %[[#LABEL:]] = trunc i64 %[[#LABEL_ORIGIN+1]] to i8
202  ; CHECK-NEXT:            %[[#ORIGIN:]] = trunc i64 %[[#LABEL_ORIGIN]] to i32
203
204  ; COMBINE_LOAD_PTR-NEXT: %[[#LABEL:]] = or i8 %[[#LABEL]], %[[#PS]]
205  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
206  ; COMBINE_LOAD_PTR-NEXT: %[[#ORIGIN:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#ORIGIN]]
207
208  ; CHECK-NEXT:            %a = load i64, ptr %p, align 2
209  ; CHECK-NEXT:            store i8 %[[#LABEL]], ptr @__dfsan_retval_tls, align [[ALIGN]]
210  ; CHECK-NEXT:            store i32 %[[#ORIGIN]], ptr @__dfsan_retval_origin_tls, align 4
211
212  %a = load i64, ptr %p, align 2
213  ret i64 %a
214}
215
216define i128 @load128(ptr %p) {
217  ; CHECK-LABEL: @load128.dfsan
218
219  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
220  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
221
222  ; CHECK-NEXT:            %[[#INTP:]] = ptrtoint ptr %p to i64
223  ; CHECK-NEXT:            %[[#SHADOW_OFFSET:]] = xor i64 %[[#INTP]], [[#MASK]]
224  ; CHECK-NEXT:            %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_OFFSET]] to ptr
225  ; CHECK-NEXT:            %[[#ORIGIN_ADDR:]] = add i64 %[[#SHADOW_OFFSET]], [[#ORIGIN_BASE]]
226  ; CHECK-NEXT:            %[[#ORIGIN1_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to ptr
227  ; CHECK-NEXT:            %[[#ORIGIN1:]] = load i32, ptr %[[#ORIGIN1_PTR]], align 8
228  ; CHECK-NEXT:            %[[#WIDE_SHADOW1:]] = load i64, ptr %[[#SHADOW_PTR]], align 1
229  ; CHECK-NEXT:            %[[#WIDE_SHADOW1_LO:]] = shl i64 %[[#WIDE_SHADOW1]], 32
230  ; CHECK-NEXT:            %[[#ORIGIN2_PTR:]] = getelementptr i32, ptr %[[#ORIGIN1_PTR]], i64 1
231  ; CHECK-NEXT:            %[[#ORIGIN2:]] = load i32, ptr %[[#ORIGIN2_PTR]], align 8
232  ; CHECK-NEXT:            %[[#WIDE_SHADOW2_PTR:]] = getelementptr i64, ptr %[[#SHADOW_PTR]], i64 1
233  ; CHECK-NEXT:            %[[#WIDE_SHADOW2:]] = load i64, ptr %[[#WIDE_SHADOW2_PTR]], align 1
234  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW1]], %[[#WIDE_SHADOW2]]
235  ; CHECK-NEXT:            %[[#ORIGIN3_PTR:]] = getelementptr i32, ptr %[[#ORIGIN2_PTR]], i64 1
236  ; CHECK-NEXT:            %[[#ORIGIN3:]] = load i32, ptr %[[#ORIGIN3_PTR]], align 8
237  ; CHECK-NEXT:            %[[#WIDE_SHADOW2_LO:]] = shl i64 %[[#WIDE_SHADOW2]], 32
238  ; CHECK-NEXT:            %[[#ORIGIN4_PTR:]] = getelementptr i32, ptr %[[#ORIGIN3_PTR]], i64 1
239  ; CHECK-NEXT:            %[[#ORIGIN4:]] = load i32, ptr %[[#ORIGIN4_PTR]], align 8
240  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
241  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
242  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
243  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
244  ; CHECK-NEXT:            %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
245  ; CHECK-NEXT:            %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
246  ; CHECK-NEXT:            %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i8
247  ; CHECK-NEXT:            %[[#SHADOW1_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW1_LO]], 0
248  ; CHECK-NEXT:            %[[#ORIGIN12:]] = select i1 %[[#SHADOW1_LO_NZ]], i32 %[[#ORIGIN1]], i32 %[[#ORIGIN2]]
249  ; CHECK-NEXT:            %[[#SHADOW2_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2]], 0
250  ; CHECK-NEXT:            %[[#ORIGIN124:]] = select i1 %[[#SHADOW2_NZ]], i32 %[[#ORIGIN4]], i32 %[[#ORIGIN12]]
251  ; CHECK-NEXT:            %[[#SHADOW2_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2_LO]], 0
252  ; CHECK-NEXT:            %[[#ORIGIN:]] = select i1 %[[#SHADOW2_LO_NZ]], i32 %[[#ORIGIN3]], i32 %[[#ORIGIN124]]
253
254  ; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i8 %[[#SHADOW]], %[[#PS]]
255  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
256  ; COMBINE_LOAD_PTR-NEXT: %[[#ORIGIN:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#ORIGIN]]
257
258  ; CHECK-NEXT:            %a = load i128, ptr %p, align 8
259  ; CHECK-NEXT:            store i8 %[[#SHADOW]], ptr @__dfsan_retval_tls, align [[ALIGN]]
260  ; CHECK-NEXT:            store i32 %[[#ORIGIN]], ptr @__dfsan_retval_origin_tls, align 4
261
262  %a = load i128, ptr %p
263  ret i128 %a
264}
265
266define i17 @load17(ptr %p) {
267  ; CHECK-LABEL: @load17.dfsan
268
269  ; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
270  ; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
271
272  ; CHECK-NEXT: %[[#LABEL_ORIGIN:]] = call zeroext i64 @__dfsan_load_label_and_origin(ptr %p, i64 3)
273  ; CHECK-NEXT: %[[#LABEL_ORIGIN_H32:]] = lshr i64 %[[#LABEL_ORIGIN]], 32
274  ; CHECK-NEXT: %[[#LABEL:]] = trunc i64 %[[#LABEL_ORIGIN_H32]] to i8
275  ; CHECK-NEXT: %[[#ORIGIN:]] = trunc i64 %[[#LABEL_ORIGIN]] to i32
276
277  ; COMBINE_LOAD_PTR-NEXT: %[[#LABEL:]] = or i8 %[[#LABEL]], %[[#PS]]
278  ; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i8 %[[#PS]], 0
279  ; COMBINE_LOAD_PTR-NEXT: %[[#ORIGIN:]] = select i1 %[[#NZ]], i32 %[[#PO]], i32 %[[#ORIGIN]]
280
281  ; CHECK-NEXT: %a = load i17, ptr %p, align 4
282  ; CHECK-NEXT: store i8 %[[#LABEL]], ptr @__dfsan_retval_tls, align [[ALIGN]]
283  ; CHECK-NEXT: store i32 %[[#ORIGIN]], ptr @__dfsan_retval_origin_tls, align 4
284
285  %a = load i17, ptr %p, align 4
286  ret i17 %a
287}
288