• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -bounds-checking -S | FileCheck %s
2; RUN: opt < %s -passes=bounds-checking -S | FileCheck %s
3target datalayout = "e-p:64:64:64-p1:16:16:16-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"
4
5@.str = private constant [8 x i8] c"abcdefg\00"   ; <[8 x i8]*>
6
7@.str_as1 = private addrspace(1) constant [8 x i8] c"abcdefg\00"   ; <[8 x i8] addrspace(1)*>
8
9
10declare noalias i8* @malloc(i64) nounwind
11declare noalias i8* @calloc(i64, i64) nounwind
12declare noalias i8* @realloc(i8* nocapture, i64) nounwind
13
14; CHECK: @f1
15define void @f1() nounwind {
16  %1 = tail call i8* @malloc(i64 32)
17  %2 = bitcast i8* %1 to i32*
18  %idx = getelementptr inbounds i32, i32* %2, i64 2
19; CHECK-NOT: trap
20  store i32 3, i32* %idx, align 4
21  ret void
22}
23
24; CHECK: @f2
25define void @f2() nounwind {
26  %1 = tail call i8* @malloc(i64 32)
27  %2 = bitcast i8* %1 to i32*
28  %idx = getelementptr inbounds i32, i32* %2, i64 8
29; CHECK: trap
30  store i32 3, i32* %idx, align 4
31  ret void
32}
33
34; CHECK: @f3
35define void @f3(i64 %x) nounwind {
36  %1 = tail call i8* @calloc(i64 4, i64 %x)
37  %2 = bitcast i8* %1 to i32*
38  %idx = getelementptr inbounds i32, i32* %2, i64 8
39; CHECK: mul i64 4, %
40; CHECK: sub i64 {{.*}}, 32
41; CHECK-NEXT: icmp ult i64 {{.*}}, 32
42; CHECK-NEXT: icmp ult i64 {{.*}}, 4
43; CHECK-NEXT: or i1
44; CHECK: trap
45  store i32 3, i32* %idx, align 4
46  ret void
47}
48
49; CHECK: @f4
50define void @f4(i64 %x) nounwind {
51  %1 = tail call i8* @realloc(i8* null, i64 %x) nounwind
52  %2 = bitcast i8* %1 to i32*
53  %idx = getelementptr inbounds i32, i32* %2, i64 8
54; CHECK: trap
55  %3 = load i32, i32* %idx, align 4
56  ret void
57}
58
59; CHECK: @f5
60define void @f5(i64 %x) nounwind {
61  %idx = getelementptr inbounds [8 x i8], [8 x i8]* @.str, i64 0, i64 %x
62; CHECK: trap
63  %1 = load i8, i8* %idx, align 4
64  ret void
65}
66
67define void @f5_as1(i64 %x) nounwind {
68; CHECK: @f5_as1
69  %idx = getelementptr inbounds [8 x i8], [8 x i8] addrspace(1)* @.str_as1, i64 0, i64 %x
70  ; CHECK: sub i16
71  ; CHECK: icmp ult i16
72; CHECK: trap
73  %1 = load i8, i8 addrspace(1)* %idx, align 4
74  ret void
75}
76
77; CHECK: @f6
78define void @f6(i64 %x) nounwind {
79  %1 = alloca i128
80; CHECK-NOT: trap
81  %2 = load i128, i128* %1, align 4
82  ret void
83}
84
85; CHECK: @f7
86define void @f7(i64 %x) nounwind {
87  %1 = alloca i128, i64 %x
88; CHECK: mul i64 16,
89; CHECK: trap
90  %2 = load i128, i128* %1, align 4
91  ret void
92}
93
94; CHECK: @f8
95define void @f8() nounwind {
96  %1 = alloca i128
97  %2 = alloca i128
98  %3 = select i1 undef, i128* %1, i128* %2
99; CHECK-NOT: trap
100  %4 = load i128, i128* %3, align 4
101  ret void
102}
103
104; CHECK: @f9
105define void @f9(i128* %arg) nounwind {
106  %1 = alloca i128
107  %2 = select i1 undef, i128* %arg, i128* %1
108; CHECK-NOT: trap
109  %3 = load i128, i128* %2, align 4
110  ret void
111}
112
113; CHECK: @f10
114define void @f10(i64 %x, i64 %y) nounwind {
115  %1 = alloca i128, i64 %x
116  %2 = alloca i128, i64 %y
117  %3 = select i1 undef, i128* %1, i128* %2
118; CHECK: select
119; CHECK: select
120; CHECK: trap
121  %4 = load i128, i128* %3, align 4
122  ret void
123}
124
125; CHECK: @f11
126define void @f11(i128* byval %x) nounwind {
127  %1 = bitcast i128* %x to i8*
128  %2 = getelementptr inbounds i8, i8* %1, i64 16
129; CHECK: br label
130  %3 = load i8, i8* %2, align 4
131  ret void
132}
133
134; CHECK: @f11_as1
135define void @f11_as1(i128 addrspace(1)* byval %x) nounwind {
136  %1 = bitcast i128 addrspace(1)* %x to i8 addrspace(1)*
137  %2 = getelementptr inbounds i8, i8 addrspace(1)* %1, i16 16
138; CHECK: br label
139  %3 = load i8, i8 addrspace(1)* %2, align 4
140  ret void
141}
142
143; CHECK: @f12
144define i64 @f12(i64 %x, i64 %y) nounwind {
145  %1 = tail call i8* @calloc(i64 1, i64 %x)
146; CHECK: mul i64 %y, 8
147  %2 = bitcast i8* %1 to i64*
148  %3 = getelementptr inbounds i64, i64* %2, i64 %y
149  %4 = load i64, i64* %3, align 8
150  ret i64 %4
151}
152
153; PR17402
154; CHECK-LABEL: @f13
155define void @f13() nounwind {
156entry:
157  br label %alive
158
159dead:
160  ; Self-refential GEPs can occur in dead code.
161  %incdec.ptr = getelementptr inbounds i32, i32* %incdec.ptr, i64 1
162  ; CHECK: %incdec.ptr = getelementptr inbounds i32, i32* %incdec.ptr
163  %l = load i32, i32* %incdec.ptr
164  br label %alive
165
166alive:
167  ret void
168}
169