xref: /llvm-project/llvm/test/Instrumentation/BoundsChecking/runtimes.ll (revision ef92e6b99fc2a881f70c4e21bbdd6ae7a0c446c8)
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
4
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
11;
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
15target 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"
16
17define 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:.*]]
27; TR:       [[BB7]]:
28; TR-NEXT:    [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
29; TR-NEXT:    ret void
30; TR:       [[TRAP]]:
31; TR-NEXT:    call void @llvm.trap() #[[ATTR2:[0-9]+]], !nosanitize [[META0]]
32; TR-NEXT:    unreachable, !nosanitize [[META0]]
33;
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:.*]]
43; RT:       [[BB7]]:
44; RT-NEXT:    [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4
45; RT-NEXT:    ret void
46; RT:       [[TRAP]]:
47; RT-NEXT:    call void @__ubsan_handle_local_out_of_bounds() #[[ATTR0]], !nosanitize [[META0]]
48; RT-NEXT:    br label %[[BB7]], !nosanitize [[META0]]
49;
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]]
65;
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]]
81;
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]]
97;
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]]
113;
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]]
129;
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]]
138;
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]]
141;
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]]:
148;
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]]
151;
152; TR-GUARD-COMMON:      unreachable, !nosanitize [[META0]]
153;
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:.*]]
165; RT-GUARD:       [[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]]
171;
172  %1 = alloca i128, i64 %x
173  %3 = load i128, ptr %1, align 4
174  ret void
175}
176
177;.
178; TR: attributes #[[ATTR0]] = { nounwind }
179; TR: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) }
180; TR: attributes #[[ATTR2]] = { noreturn nounwind }
181;.
182; RT: attributes #[[ATTR0]] = { nounwind }
183;.
184; TR-NOMERGE: attributes #[[ATTR0]] = { nounwind }
185; TR-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind }
186; TR-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
187;.
188; RT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
189; RT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind }
190;.
191; RTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
192; RTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind }
193; RTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
194;.
195; MINRT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
196; MINRT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind }
197;.
198; MINRTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind }
199; MINRTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind }
200; MINRTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind }
201;.
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 }
206;.
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 }
210;.
211; TR: [[META0]] = !{}
212;.
213; RT: [[META0]] = !{}
214;.
215; TR-NOMERGE: [[META0]] = !{}
216;.
217; RT-NOMERGE: [[META0]] = !{}
218;.
219; RTABORT-NOMERGE: [[META0]] = !{}
220;.
221; MINRT-NOMERGE: [[META0]] = !{}
222;.
223; MINRTABORT-NOMERGE: [[META0]] = !{}
224;.
225; TR-GUARD: [[META0]] = !{}
226;.
227; RT-GUARD: [[META0]] = !{}
228;.
229