blob: 216dba874ccb20939d5d6b07c3ba94a242e46f68 [file] [log] [blame]
Benjamin Kramer691363e2015-03-21 15:36:21 +00001; Test that the memchr library call simplifier works correctly.
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
Benjamin Kramer7857d722015-03-21 21:09:33 +00004target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
Benjamin Kramer691363e2015-03-21 15:36:21 +00005
6@hello = constant [14 x i8] c"hello world\5Cn\00"
7@hellonull = constant [14 x i8] c"hello\00world\5Cn\00"
8@null = constant [1 x i8] zeroinitializer
Benjamin Kramer7857d722015-03-21 21:09:33 +00009@newlines = constant [3 x i8] c"\0D\0A\00"
10@single = constant [2 x i8] c"\1F\00"
11@spaces = constant [4 x i8] c" \0D\0A\00"
Benjamin Kramerd6aa0ec2015-03-21 22:04:26 +000012@negative = constant [3 x i8] c"\FF\FE\00"
Benjamin Kramer691363e2015-03-21 15:36:21 +000013@chp = global i8* zeroinitializer
14
15declare i8* @memchr(i8*, i32, i32)
16
17define void @test1() {
18; CHECK-LABEL: @test1
19; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6)
20; CHECK-NOT: call i8* @memchr
21; CHECK: ret void
22
23 %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
24 %dst = call i8* @memchr(i8* %str, i32 119, i32 14)
25 store i8* %dst, i8** @chp
26 ret void
27}
28
29define void @test2() {
30; CHECK-LABEL: @test2
31; CHECK: store i8* null, i8** @chp, align 4
32; CHECK-NOT: call i8* @memchr
33; CHECK: ret void
34
35 %str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
36 %dst = call i8* @memchr(i8* %str, i32 119, i32 1)
37 store i8* %dst, i8** @chp
38 ret void
39}
40
41define void @test3() {
42; CHECK-LABEL: @test3
43; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
44; CHECK-NOT: call i8* @memchr
45; CHECK: ret void
46
47 %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
48 %dst = call i8* @memchr(i8* %src, i32 0, i32 14)
49 store i8* %dst, i8** @chp
50 ret void
51}
52
53define void @test4(i32 %chr) {
54; CHECK-LABEL: @test4
55; CHECK: call i8* @memchr
56; CHECK-NOT: call i8* @memchr
57; CHECK: ret void
58
59 %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
60 %dst = call i8* @memchr(i8* %src, i32 %chr, i32 14)
61 store i8* %dst, i8** @chp
62 ret void
63}
64
65define void @test5() {
66; CHECK-LABEL: @test5
67; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
68; CHECK-NOT: call i8* @memchr
69; CHECK: ret void
70
71 %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
72 %dst = call i8* @memchr(i8* %src, i32 65280, i32 14)
73 store i8* %dst, i8** @chp
74 ret void
75}
76
77define void @test6() {
78; CHECK-LABEL: @test6
79; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6)
80; CHECK-NOT: call i8* @memchr
81; CHECK: ret void
82
83 %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
84; Overflow, but we still find the right thing.
85 %dst = call i8* @memchr(i8* %src, i32 119, i32 100)
86 store i8* %dst, i8** @chp
87 ret void
88}
89
90define void @test7() {
91; CHECK-LABEL: @test7
92; CHECK: store i8* null, i8** @chp, align 4
93; CHECK-NOT: call i8* @memchr
94; CHECK: ret void
95
96 %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
97; Overflow
98 %dst = call i8* @memchr(i8* %src, i32 120, i32 100)
99 store i8* %dst, i8** @chp
100 ret void
101}
102
103define void @test8() {
104; CHECK-LABEL: @test8
105; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6)
106; CHECK-NOT: call i8* @memchr
107; CHECK: ret void
108
109 %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 0
110 %dst = call i8* @memchr(i8* %str, i32 119, i32 14)
111 store i8* %dst, i8** @chp
112 ret void
113}
114
115define void @test9() {
116; CHECK-LABEL: @test9
117; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6)
118; CHECK-NOT: call i8* @memchr
119; CHECK: ret void
120
121 %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 2
122 %dst = call i8* @memchr(i8* %str, i32 119, i32 12)
123 store i8* %dst, i8** @chp
124 ret void
125}
Benjamin Kramer7857d722015-03-21 21:09:33 +0000126
127define void @test10() {
128; CHECK-LABEL: @test10
129; CHECK: store i8* null, i8** @chp, align 4
130; CHECK-NOT: call i8* @memchr
131; CHECK: ret void
132
133 %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
134 %dst = call i8* @memchr(i8* %str, i32 119, i32 6)
135 store i8* %dst, i8** @chp
136 ret void
137}
138
139; Check transformation memchr("\r\n", C, 2) != nullptr -> (C & 9216) != 0
140define i1 @test11(i32 %C) {
141; CHECK-LABEL: @test11
142; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 %C to i16
143; CHECK-NEXT: %memchr.bounds = icmp ult i16 [[TRUNC]], 16
144; CHECK-NEXT: [[SHL:%.*]] = shl i16 1, [[TRUNC]]
145; CHECK-NEXT: [[AND:%.*]] = and i16 [[SHL]], 9216
146; CHECK-NEXT: %memchr.bits = icmp ne i16 [[AND]], 0
147; CHECK-NEXT: %memchr = and i1 %memchr.bounds, %memchr.bits
148; CHECK-NEXT: ret i1 %memchr
149
150 %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C, i32 2)
151 %cmp = icmp ne i8* %dst, null
152 ret i1 %cmp
153}
154
155; No 64 bits here
156define i1 @test12(i32 %C) {
157; CHECK-LABEL: @test12
158; CHECK-NEXT: %dst = call i8* @memchr(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 %C, i32 3)
159; CHECK-NEXT: %cmp = icmp ne i8* %dst, null
160; CHECK-NEXT: ret i1 %cmp
161
162 %dst = call i8* @memchr(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i64 0, i64 0), i32 %C, i32 3)
163 %cmp = icmp ne i8* %dst, null
164 ret i1 %cmp
165}
166
167define i1 @test13(i32 %C) {
168; CHECK-LABEL: @test13
169; CHECK-NEXT: %memchr.bounds = icmp ult i32 %C, 32
170; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, %C
171; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], -2147483647
172; CHECK-NEXT: %memchr.bits = icmp ne i32 [[AND]], 0
173; CHECK-NEXT: %memchr = and i1 %memchr.bounds, %memchr.bits
174; CHECK-NEXT: ret i1 %memchr
175
176 %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 2)
177 %cmp = icmp ne i8* %dst, null
178 ret i1 %cmp
179}
180
181define i1 @test14(i32 %C) {
182; CHECK-LABEL: @test14
183; CHECK-NEXT: icmp eq i32 %C, 31
184; CHECK-NEXT: ret
185
186 %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 1)
187 %cmp = icmp ne i8* %dst, null
188 ret i1 %cmp
189}
Benjamin Kramerd6aa0ec2015-03-21 22:04:26 +0000190
191define i1 @test15(i32 %C) {
192; CHECK-LABEL: @test15
193; CHECK-NEXT: %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 %C, i32 3)
194; CHECK-NEXT: %cmp = icmp ne i8* %dst, null
195; CHECK-NEXT: ret i1 %cmp
196
197 %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i64 0, i64 0), i32 %C, i32 3)
198 %cmp = icmp ne i8* %dst, null
199 ret i1 %cmp
200}