1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
2 ; RUN: opt < %s -passes='bounds-checking<trap;merge>' -S | FileCheck %s --check-prefixes=TR
3 ; RUN: opt < %s -passes='bounds-checking<rt;merge>' -S | FileCheck %s --check-prefixes=RT
5 ; RUN: opt < %s -passes=bounds-checking -S | FileCheck %s --check-prefixes=TR-NOMERGE
6 ; RUN: opt < %s -passes='bounds-checking<trap>' -S | FileCheck %s --check-prefixes=TR-NOMERGE
7 ; RUN: opt < %s -passes='bounds-checking<rt>' -S | FileCheck %s --check-prefixes=RT-NOMERGE
8 ; RUN: opt < %s -passes='bounds-checking<rt-abort>' -S | FileCheck %s --check-prefixes=RTABORT-NOMERGE
9 ; RUN: opt < %s -passes='bounds-checking<min-rt>' -S | FileCheck %s --check-prefixes=MINRT-NOMERGE
10 ; RUN: opt < %s -passes='bounds-checking<min-rt-abort>' -S | FileCheck %s --check-prefixes=MINRTABORT-NOMERGE
12 ; RUN: opt < %s -passes='bounds-checking<trap;guard=3>' -S | FileCheck %s --check-prefixes=TR-GUARD-COMMON,TR-GUARD-THREE
13 ; RUN: opt < %s -passes='bounds-checking<trap;guard=13>' -S | FileCheck %s --check-prefixes=TR-GUARD-COMMON,TR-GUARD-THIRTEEN
14 ; RUN: opt < %s -passes='bounds-checking<rt;guard=-5>' -S | FileCheck %s --check-prefixes=RT-GUARD
15 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"
17 define void @f1(i64 %x) nounwind {
18 ; TR-LABEL: define void @f1(
19 ; TR-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
20 ; TR-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
21 ; TR-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
22 ; TR-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
23 ; TR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
24 ; TR-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
25 ; TR-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
26 ; TR-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
28 ; TR-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
31 ; TR-NEXT: call void @llvm.trap() #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
32 ; TR-NEXT: unreachable, !nosanitize [[META0]]
34 ; RT-LABEL: define void @f1(
35 ; RT-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
36 ; RT-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
37 ; RT-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
38 ; RT-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
39 ; RT-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
40 ; RT-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
41 ; RT-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
42 ; RT-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
44 ; RT-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
47 ; RT-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR0]], !nosanitize [[META0]]
48 ; RT-NEXT: br label %[[BB7]], !nosanitize [[META0]]
50 ; TR-NOMERGE-LABEL: define void @f1(
51 ; TR-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
52 ; TR-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
53 ; TR-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
54 ; TR-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
55 ; TR-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
56 ; TR-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
57 ; TR-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
58 ; TR-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
59 ; TR-NOMERGE: [[BB7]]:
60 ; TR-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
61 ; TR-NOMERGE-NEXT: ret void
62 ; TR-NOMERGE: [[TRAP]]:
63 ; TR-NOMERGE-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
64 ; TR-NOMERGE-NEXT: unreachable, !nosanitize [[META0]]
66 ; RT-NOMERGE-LABEL: define void @f1(
67 ; RT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
68 ; RT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
69 ; RT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
70 ; RT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
71 ; RT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
72 ; RT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
73 ; RT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
74 ; RT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
75 ; RT-NOMERGE: [[BB7]]:
76 ; RT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
77 ; RT-NOMERGE-NEXT: ret void
78 ; RT-NOMERGE: [[TRAP]]:
79 ; RT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR1:[0-9]+]], !nosanitize [[META0]]
80 ; RT-NOMERGE-NEXT: br label %[[BB7]], !nosanitize [[META0]]
82 ; RTABORT-NOMERGE-LABEL: define void @f1(
83 ; RTABORT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
84 ; RTABORT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
85 ; RTABORT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
86 ; RTABORT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
87 ; RTABORT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
88 ; RTABORT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
89 ; RTABORT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
90 ; RTABORT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
91 ; RTABORT-NOMERGE: [[BB7]]:
92 ; RTABORT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
93 ; RTABORT-NOMERGE-NEXT: ret void
94 ; RTABORT-NOMERGE: [[TRAP]]:
95 ; RTABORT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_abort() #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
96 ; RTABORT-NOMERGE-NEXT: unreachable, !nosanitize [[META0]]
98 ; MINRT-NOMERGE-LABEL: define void @f1(
99 ; MINRT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
100 ; MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
101 ; MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
102 ; MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
103 ; MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
104 ; MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
105 ; MINRT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
106 ; MINRT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
107 ; MINRT-NOMERGE: [[BB7]]:
108 ; MINRT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
109 ; MINRT-NOMERGE-NEXT: ret void
110 ; MINRT-NOMERGE: [[TRAP]]:
111 ; MINRT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_minimal() #[[ATTR1:[0-9]+]], !nosanitize [[META0]]
112 ; MINRT-NOMERGE-NEXT: br label %[[BB7]], !nosanitize [[META0]]
114 ; MINRTABORT-NOMERGE-LABEL: define void @f1(
115 ; MINRTABORT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
116 ; MINRTABORT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
117 ; MINRTABORT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
118 ; MINRTABORT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
119 ; MINRTABORT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
120 ; MINRTABORT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
121 ; MINRTABORT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
122 ; MINRTABORT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]]
123 ; MINRTABORT-NOMERGE: [[BB7]]:
124 ; MINRTABORT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
125 ; MINRTABORT-NOMERGE-NEXT: ret void
126 ; MINRTABORT-NOMERGE: [[TRAP]]:
127 ; MINRTABORT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_minimal_abort() #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
128 ; MINRTABORT-NOMERGE-NEXT: unreachable, !nosanitize [[META0]]
130 ; TR-GUARD-COMMON-LABEL: define void @f1(
131 ; TR-GUARD-COMMON-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
132 ; TR-GUARD-COMMON-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
133 ; TR-GUARD-COMMON-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
134 ; TR-GUARD-COMMON-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
135 ; TR-GUARD-COMMON-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
136 ; TR-GUARD-COMMON-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
137 ; TR-GUARD-COMMON-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
139 ; TR-GUARD-THREE: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META0]]
140 ; TR-GUARD-THIRTEEN: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 13), !nosanitize [[META0]]
142 ; TR-GUARD-COMMON: [[TMP8:%.*]] = and i1 [[TMP6]], [[TMP7]], !nosanitize [[META0]]
143 ; TR-GUARD-COMMON-NEXT: br i1 [[TMP8]], label %[[TRAP:.*]], label %[[BB9:.*]]
144 ; TR-GUARD-COMMON: [[BB9]]:
145 ; TR-GUARD-COMMON-NEXT: [[TMP10:%.*]] = load i128, ptr [[TMP2]], align 4
146 ; TR-GUARD-COMMON-NEXT: ret void
147 ; TR-GUARD-COMMON: [[TRAP]]:
149 ; TR-GUARD-THREE: call void @llvm.ubsantrap(i8 3) #[[ATTR3:[0-9]+]], !nosanitize [[META0]]
150 ; TR-GUARD-THIRTEEN: call void @llvm.ubsantrap(i8 13) #[[ATTR3:[0-9]+]], !nosanitize [[META0]]
152 ; TR-GUARD-COMMON: unreachable, !nosanitize [[META0]]
154 ; RT-GUARD-LABEL: define void @f1(
155 ; RT-GUARD-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
156 ; RT-GUARD-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]]
157 ; RT-GUARD-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8
158 ; RT-GUARD-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]]
159 ; RT-GUARD-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]]
160 ; RT-GUARD-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]]
161 ; RT-GUARD-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]]
162 ; RT-GUARD-NEXT: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 -5), !nosanitize [[META0]]
163 ; RT-GUARD-NEXT: [[TMP8:%.*]] = and i1 [[TMP6]], [[TMP7]], !nosanitize [[META0]]
164 ; RT-GUARD-NEXT: br i1 [[TMP8]], label %[[TRAP:.*]], label %[[BB9:.*]]
166 ; RT-GUARD-NEXT: [[TMP10:%.*]] = load i128, ptr [[TMP2]], align 4
167 ; RT-GUARD-NEXT: ret void
168 ; RT-GUARD: [[TRAP]]:
169 ; RT-GUARD-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
170 ; RT-GUARD-NEXT: br label %[[BB9]], !nosanitize [[META0]]
172 %1 = alloca i128, i64 %x
173 %3 = load i128, ptr %1, align 4
178 ; TR: attributes #[[ATTR0]] = { nounwind }
179 ; TR: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
180 ; TR: attributes #[[ATTR2]] = { noreturn nounwind }
182 ; RT: attributes #[[ATTR0]] = { nounwind }
184 ; TR-NOMERGE: attributes #[[ATTR0]] = { nounwind }
185 ; TR-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind }
186 ; TR-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
188 ; RT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
189 ; RT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind }
191 ; RTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
192 ; RTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind }
193 ; RTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
195 ; MINRT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
196 ; MINRT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind }
198 ; MINRTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
199 ; MINRTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind }
200 ; MINRTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
202 ; TR-GUARD: attributes #[[ATTR0]] = { nounwind }
203 ; TR-GUARD: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
204 ; TR-GUARD: attributes #[[ATTR2:[0-9]+]] = { cold noreturn nounwind }
205 ; TR-GUARD: attributes #[[ATTR3]] = { nomerge noreturn nounwind }
207 ; RT-GUARD: attributes #[[ATTR0]] = { nounwind }
208 ; RT-GUARD: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
209 ; RT-GUARD: attributes #[[ATTR2]] = { nomerge nounwind }
211 ; TR: [[META0]] = !{}
213 ; RT: [[META0]] = !{}
215 ; TR-NOMERGE: [[META0]] = !{}
217 ; RT-NOMERGE: [[META0]] = !{}
219 ; RTABORT-NOMERGE: [[META0]] = !{}
221 ; MINRT-NOMERGE: [[META0]] = !{}
223 ; MINRTABORT-NOMERGE: [[META0]] = !{}
225 ; TR-GUARD: [[META0]] = !{}
227 ; RT-GUARD: [[META0]] = !{}