Skip to content

Commit 6099639

Browse files
authored
[clang] Precommit test for llvm.allow.ubsan.check() (#87435)
1 parent 5822ca5 commit 6099639

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
2+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s
3+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -fsanitize-trap=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=TRAP
4+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=RECOVER
5+
6+
7+
// CHECK-LABEL: define dso_local i32 @div(
8+
// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
9+
// CHECK-NEXT: entry:
10+
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
11+
// CHECK-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
12+
// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
13+
// CHECK-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
14+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
15+
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
16+
// CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0, !nosanitize [[META2:![0-9]+]]
17+
// CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP0]], -2147483648, !nosanitize [[META2]]
18+
// CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
19+
// CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
20+
// CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
21+
// CHECK-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
22+
// CHECK: handler.divrem_overflow:
23+
// CHECK-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
24+
// CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
25+
// CHECK-NEXT: call void @__ubsan_handle_divrem_overflow_abort(ptr @[[GLOB1:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
26+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
27+
// CHECK: cont:
28+
// CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
29+
// CHECK-NEXT: ret i32 [[DIV]]
30+
//
31+
// TRAP-LABEL: define dso_local i32 @div(
32+
// TRAP-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
33+
// TRAP-NEXT: entry:
34+
// TRAP-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
35+
// TRAP-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
36+
// TRAP-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
37+
// TRAP-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
38+
// TRAP-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
39+
// TRAP-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
40+
// TRAP-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0, !nosanitize [[META2:![0-9]+]]
41+
// TRAP-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP0]], -2147483648, !nosanitize [[META2]]
42+
// TRAP-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
43+
// TRAP-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
44+
// TRAP-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
45+
// TRAP-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
46+
// TRAP: trap:
47+
// TRAP-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
48+
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
49+
// TRAP: cont:
50+
// TRAP-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
51+
// TRAP-NEXT: ret i32 [[DIV]]
52+
//
53+
// RECOVER-LABEL: define dso_local i32 @div(
54+
// RECOVER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
55+
// RECOVER-NEXT: entry:
56+
// RECOVER-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
57+
// RECOVER-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
58+
// RECOVER-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
59+
// RECOVER-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
60+
// RECOVER-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
61+
// RECOVER-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
62+
// RECOVER-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0, !nosanitize [[META2:![0-9]+]]
63+
// RECOVER-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP0]], -2147483648, !nosanitize [[META2]]
64+
// RECOVER-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
65+
// RECOVER-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
66+
// RECOVER-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
67+
// RECOVER-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
68+
// RECOVER: handler.divrem_overflow:
69+
// RECOVER-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
70+
// RECOVER-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
71+
// RECOVER-NEXT: call void @__ubsan_handle_divrem_overflow(ptr @[[GLOB1:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
72+
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
73+
// RECOVER: cont:
74+
// RECOVER-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
75+
// RECOVER-NEXT: ret i32 [[DIV]]
76+
//
77+
int div(int x, int y) {
78+
return x / y;
79+
}
80+
81+
// CHECK-LABEL: define dso_local i32 @null(
82+
// CHECK-SAME: ptr noundef [[X:%.*]]) #[[ATTR0]] {
83+
// CHECK-NEXT: entry:
84+
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
85+
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
86+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
87+
// CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
88+
// CHECK-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
89+
// CHECK: handler.type_mismatch:
90+
// CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
91+
// CHECK-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB2:[0-9]+]], i64 [[TMP2]]) #[[ATTR3]], !nosanitize [[META2]]
92+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
93+
// CHECK: cont:
94+
// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
95+
// CHECK-NEXT: ret i32 [[TMP3]]
96+
//
97+
// TRAP-LABEL: define dso_local i32 @null(
98+
// TRAP-SAME: ptr noundef [[X:%.*]]) #[[ATTR0]] {
99+
// TRAP-NEXT: entry:
100+
// TRAP-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
101+
// TRAP-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
102+
// TRAP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
103+
// TRAP-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
104+
// TRAP-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
105+
// TRAP: trap:
106+
// TRAP-NEXT: call void @llvm.ubsantrap(i8 22) #[[ATTR3]], !nosanitize [[META2]]
107+
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
108+
// TRAP: cont:
109+
// TRAP-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP0]], align 4
110+
// TRAP-NEXT: ret i32 [[TMP2]]
111+
//
112+
// RECOVER-LABEL: define dso_local i32 @null(
113+
// RECOVER-SAME: ptr noundef [[X:%.*]]) #[[ATTR0]] {
114+
// RECOVER-NEXT: entry:
115+
// RECOVER-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8
116+
// RECOVER-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
117+
// RECOVER-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
118+
// RECOVER-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
119+
// RECOVER-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
120+
// RECOVER: handler.type_mismatch:
121+
// RECOVER-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
122+
// RECOVER-NEXT: call void @__ubsan_handle_type_mismatch_v1(ptr @[[GLOB2:[0-9]+]], i64 [[TMP2]]) #[[ATTR3]], !nosanitize [[META2]]
123+
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
124+
// RECOVER: cont:
125+
// RECOVER-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
126+
// RECOVER-NEXT: ret i32 [[TMP3]]
127+
//
128+
int null(int* x) {
129+
return *x;
130+
}
131+
132+
// CHECK-LABEL: define dso_local i32 @overflow(
133+
// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
134+
// CHECK-NEXT: entry:
135+
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
136+
// CHECK-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
137+
// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
138+
// CHECK-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
139+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
140+
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
141+
// CHECK-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP0]], i32 [[TMP1]]), !nosanitize [[META2]]
142+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
143+
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
144+
// CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
145+
// CHECK-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
146+
// CHECK: handler.add_overflow:
147+
// CHECK-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
148+
// CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
149+
// CHECK-NEXT: call void @__ubsan_handle_add_overflow_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3]], !nosanitize [[META2]]
150+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
151+
// CHECK: cont:
152+
// CHECK-NEXT: ret i32 [[TMP3]]
153+
//
154+
// TRAP-LABEL: define dso_local i32 @overflow(
155+
// TRAP-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
156+
// TRAP-NEXT: entry:
157+
// TRAP-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
158+
// TRAP-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
159+
// TRAP-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
160+
// TRAP-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
161+
// TRAP-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
162+
// TRAP-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
163+
// TRAP-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP0]], i32 [[TMP1]]), !nosanitize [[META2]]
164+
// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
165+
// TRAP-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
166+
// TRAP-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
167+
// TRAP-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
168+
// TRAP: trap:
169+
// TRAP-NEXT: call void @llvm.ubsantrap(i8 0) #[[ATTR3]], !nosanitize [[META2]]
170+
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
171+
// TRAP: cont:
172+
// TRAP-NEXT: ret i32 [[TMP3]]
173+
//
174+
// RECOVER-LABEL: define dso_local i32 @overflow(
175+
// RECOVER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
176+
// RECOVER-NEXT: entry:
177+
// RECOVER-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
178+
// RECOVER-NEXT: [[Y_ADDR:%.*]] = alloca i32, align 4
179+
// RECOVER-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
180+
// RECOVER-NEXT: store i32 [[Y]], ptr [[Y_ADDR]], align 4
181+
// RECOVER-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
182+
// RECOVER-NEXT: [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
183+
// RECOVER-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP0]], i32 [[TMP1]]), !nosanitize [[META2]]
184+
// RECOVER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
185+
// RECOVER-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
186+
// RECOVER-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
187+
// RECOVER-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
188+
// RECOVER: handler.add_overflow:
189+
// RECOVER-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
190+
// RECOVER-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
191+
// RECOVER-NEXT: call void @__ubsan_handle_add_overflow(ptr @[[GLOB3:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3]], !nosanitize [[META2]]
192+
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
193+
// RECOVER: cont:
194+
// RECOVER-NEXT: ret i32 [[TMP3]]
195+
//
196+
int overflow(int x, int y) {
197+
return x + y;
198+
}
199+
//.
200+
// CHECK: [[META2]] = !{}
201+
// CHECK: [[PROF3]] = !{!"branch_weights", i32 1048575, i32 1}
202+
//.
203+
// TRAP: [[META2]] = !{}
204+
//.
205+
// RECOVER: [[META2]] = !{}
206+
// RECOVER: [[PROF3]] = !{!"branch_weights", i32 1048575, i32 1}
207+
//.

0 commit comments

Comments
 (0)