[clang-tidy][use-internal-linkage] fix false positive for consteval function (#122141)
[llvm-project.git] / llvm / test / Instrumentation / DataFlowSanitizer / abilist_aggregate.ll
blob2cf57716172b8d7ea9a86fc8b4d6909a0f845d28
1 ; RUN: opt < %s -passes=dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
2 target 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"
3 target triple = "x86_64-unknown-linux-gnu"
5 ; CHECK: define { i1, i7 } @functional({ i32, i1 } %a, [2 x i7] %b)
6 define {i1, i7} @functional({i32, i1} %a, [2 x i7] %b) {
7   %a1 = extractvalue {i32, i1} %a, 1
8   %b0 = extractvalue [2 x i7] %b, 0
9   %r0 = insertvalue {i1, i7} undef, i1 %a1, 0
10   %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1
11   ret {i1, i7} %r1
14 define {i1, i7} @call_functional({i32, i1} %a, [2 x i7] %b) {
15   ; CHECK-LABEL: @call_functional.dfsan
16   ; CHECK-NEXT: %[[#REG:]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
17   ; CHECK-NEXT: %[[#REG+1]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
18   ; CHECK-NEXT: %[[#REG+2]] = extractvalue { i8, i8 } %[[#REG+1]], 0
19   ; CHECK-NEXT: %[[#REG+3]] = extractvalue { i8, i8 } %[[#REG+1]], 1
20   ; CHECK-NEXT: %[[#REG+4]] = or i8 %[[#REG+2]], %[[#REG+3]]
21   ; CHECK-NEXT: %[[#REG+5]] = extractvalue [2 x i8] %[[#REG]], 0
22   ; CHECK-NEXT: %[[#REG+6]] = extractvalue [2 x i8] %[[#REG]], 1
23   ; CHECK-NEXT: %[[#REG+7]] = or i8 %[[#REG+5]], %[[#REG+6]]
24   ; CHECK-NEXT: %[[#REG+8]] = or i8 %[[#REG+4]], %[[#REG+7]]
25   ; CHECK-NEXT: %[[#REG+9]] = insertvalue { i8, i8 } undef, i8 %[[#REG+8]], 0
26   ; CHECK-NEXT: %[[#REG+10]] = insertvalue { i8, i8 } %[[#REG+9]], i8 %[[#REG+8]], 1
27   ; CHECK: store { i8, i8 } %[[#REG+10]], ptr @__dfsan_retval_tls, align [[ALIGN]]
29   %r = call {i1, i7} @functional({i32, i1} %a, [2 x i7] %b)
30   ret {i1, i7} %r
33 ; CHECK: define { i1, i7 } @discard({ i32, i1 } %a, [2 x i7] %b)
34 define {i1, i7} @discard({i32, i1} %a, [2 x i7] %b) {
35   %a1 = extractvalue {i32, i1} %a, 1
36   %b0 = extractvalue [2 x i7] %b, 0
37   %r0 = insertvalue {i1, i7} undef, i1 %a1, 0
38   %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1
39   ret {i1, i7} %r1
42 define {i1, i7} @call_discard({i32, i1} %a, [2 x i7] %b) {
43   ; CHECK: @call_discard.dfsan
44   ; CHECK: store { i8, i8 } zeroinitializer, ptr @__dfsan_retval_tls, align 2
46   %r = call {i1, i7} @discard({i32, i1} %a, [2 x i7] %b)
47   ret {i1, i7} %r
50 ; CHECK: define { i1, i7 } @uninstrumented({ i32, i1 } %a, [2 x i7] %b)
51 define {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b) {
52   %a1 = extractvalue {i32, i1} %a, 1
53   %b0 = extractvalue [2 x i7] %b, 0
54   %r0 = insertvalue {i1, i7} undef, i1 %a1, 0
55   %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1
56   ret {i1, i7} %r1
59 define {i1, i7} @call_uninstrumented({i32, i1} %a, [2 x i7] %b) {
60   ; CHECK: @call_uninstrumented.dfsan
61   ; CHECK: call void @__dfsan_unimplemented
62   ; CHECK: store { i8, i8 } zeroinitializer, ptr @__dfsan_retval_tls, align 2
64   %r = call {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b)
65   ret {i1, i7} %r
68 define {i1, i7} @call_custom_with_ret({i32, i1} %a, [2 x i7] %b) {
69   ; CHECK: @call_custom_with_ret.dfsan
70   ; CHECK: %labelreturn = alloca i8, align 1
71   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
72   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
73   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
74   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
75   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
76   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
77   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
78   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
79   ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
80   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
81   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
82   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
83   ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]
84   ; CHECK: ret { i1, i7 } [[R]]
86   %r = call {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b)
87   ret {i1, i7} %r
90 define void @call_custom_without_ret({i32, i1} %a, [2 x i7] %b) {
91   ; CHECK: @call_custom_without_ret.dfsan
92   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
93   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
94   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
95   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
96   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
97   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
98   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
99   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
100   ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]])
102   call void @custom_without_ret({i32, i1} %a, [2 x i7] %b)
103   ret void
106 define void @call_custom_varg({i32, i1} %a, [2 x i7] %b) {
107   ; CHECK: @call_custom_varg.dfsan
108   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
109   ; CHECK: %labelva = alloca [1 x i8], align 1
110   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
111   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
112   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
113   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
114   ; CHECK: [[V0:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0
115   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
116   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
117   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
118   ; CHECK: store i8 [[B01]], ptr [[V0]], align 1
119   ; CHECK: [[V:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0
120   ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 zeroext [[A01]], ptr [[V]], [2 x i7] %b)
122   call void ({i32, i1}, ...) @custom_varg({i32, i1} %a, [2 x i7] %b)
123   ret void
126 define {i1, i7} @call_custom_cb({i32, i1} %a, [2 x i7] %b) {
127   ; CHECK: define { i1, i7 } @call_custom_cb.dfsan({ i32, i1 } %a, [2 x i7] %b) {
128   ; CHECK: %labelreturn = alloca i8, align 1
129   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
130   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
131   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
132   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
133   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
134   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
135   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
136   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
137   ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 zeroext 0, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
138   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
139   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
140   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
141   ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]
143   %r = call {i1, i7} @custom_cb(ptr @cb, {i32, i1} %a, [2 x i7] %b)
144   ret {i1, i7} %r
147 define {i1, i7} @custom_cb(ptr %cb, {i32, i1} %a, [2 x i7] %b) {
148   ; CHECK: define { i1, i7 } @custom_cb(ptr %cb, { i32, i1 } %a, [2 x i7] %b)
150   %r = call {i1, i7} %cb({i32, i1} %a, [2 x i7] %b)
151   ret {i1, i7} %r
154 define {i1, i7} @cb({i32, i1} %a, [2 x i7] %b) {
155   ; CHECK: define { i1, i7 } @cb.dfsan({ i32, i1 } %a, [2 x i7] %b)
156   ; CHECK: [[BL:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
157   ; CHECK: [[AL:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
158   ; CHECK: [[AL1:%.*]] = extractvalue { i8, i8 } [[AL]], 1
159   ; CHECK: [[BL0:%.*]] = extractvalue [2 x i8] [[BL]], 0
160   ; CHECK: [[RL0:%.*]] = insertvalue { i8, i8 } zeroinitializer, i8 [[AL1]], 0
161   ; CHECK: [[RL:%.*]] = insertvalue { i8, i8 } [[RL0]], i8 [[BL0]], 1
162   ; CHECK: store { i8, i8 } [[RL]], ptr @__dfsan_retval_tls, align [[ALIGN]]
164   %a1 = extractvalue {i32, i1} %a, 1
165   %b0 = extractvalue [2 x i7] %b, 0
166   %r0 = insertvalue {i1, i7} undef, i1 %a1, 0
167   %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1
168   ret {i1, i7} %r1
171 define ptr @ret_custom() {
172   ; CHECK: @ret_custom.dfsan
173   ; CHECK: store i8 0, ptr @__dfsan_retval_tls, align 2
174   ; CHECK: ret {{.*}} @"dfsw$custom_with_ret"
175   ret ptr @custom_with_ret
178 ; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_cb"(ptr %0, { i32, i1 } %1, [2 x i7] %2) {
179 ; CHECK: %labelreturn = alloca i8, align 1
180 ; COMM: TODO simplify the expression [[#mul(2,SBYTES) + max(SBYTES,2)]] to
181 ; COMM: [[#mul(3,SBYTES)]], if shadow-tls-alignment is updated to match shadow
182 ; COMM: width bytes.
183 ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 4) to ptr), align [[ALIGN:2]]
184 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
185 ; CHECK: [[CB:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]
186 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
187 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
188 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
189 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
190 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
191 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
192 ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 zeroext [[CB]], i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
193 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
194 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
195 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
196 ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]
198 define {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) {
199   ; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_with_ret"({ i32, i1 } %0, [2 x i7] %1)
200   ; CHECK: %labelreturn = alloca i8, align 1
201   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
202   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
203   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
204   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
205   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
206   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
207   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
208   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
209   ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
210   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
211   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
212   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
213   ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]
214   ; CHECK: ret { i1, i7 } [[R]]
215   %a1 = extractvalue {i32, i1} %a, 1
216   %b0 = extractvalue [2 x i7] %b, 0
217   %r0 = insertvalue {i1, i7} undef, i1 %a1, 0
218   %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1
219   ret {i1, i7} %r1
222 define void @custom_without_ret({i32, i1} %a, [2 x i7] %b) {
223   ; CHECK: define linkonce_odr void @"dfsw$custom_without_ret"({ i32, i1 } %0, [2 x i7] %1)
224   ; CHECK: [[B:%.*]] = load [2 x i8], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN:2]]
225   ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]
226   ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0
227   ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1
228   ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]
229   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
230   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
231   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
232   ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]])
233   ; CHECK: ret
234   ret void
237 define void @custom_varg({i32, i1} %a, ...) {
238   ; CHECK: define linkonce_odr void @"dfsw$custom_varg"({ i32, i1 } %0, ...)
239   ; CHECK: call void @__dfsan_vararg_wrapper
240   ; CHECK: unreachable
241   ret void
244 ; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8, i8, ptr)
245 ; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8, i8)
246 ; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8, ptr, ...)
248 ; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8, i8, i8, ptr)