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