120
|
1 ; Test that memcmp won't be converted to CLC if calls are
|
|
2 ; marked with nobuiltin, eg. for sanitizers.
|
|
3 ;
|
|
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
|
5
|
|
6 declare signext i32 @memcmp(i8 *%src1, i8 *%src2, i64 %size)
|
|
7
|
|
8 ; Zero-length comparisons should be optimized away.
|
|
9 define i32 @f1(i8 *%src1, i8 *%src2) {
|
|
10 ; CHECK-LABEL: f1:
|
|
11 ; CHECK-NOT: clc
|
|
12 ; CHECK: brasl %r14, memcmp
|
|
13 ; CHECK: br %r14
|
|
14 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 0) nobuiltin
|
|
15 ret i32 %res
|
|
16 }
|
|
17
|
|
18 ; Check a case where the result is used as an integer.
|
|
19 define i32 @f2(i8 *%src1, i8 *%src2) {
|
|
20 ; CHECK-LABEL: f2:
|
|
21 ; CHECK-NOT: clc
|
|
22 ; CHECK: brasl %r14, memcmp
|
|
23 ; CHECK: br %r14
|
|
24 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 2) nobuiltin
|
|
25 ret i32 %res
|
|
26 }
|
|
27
|
|
28 ; Check a case where the result is tested for equality.
|
|
29 define void @f3(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
30 ; CHECK-LABEL: f3:
|
|
31 ; CHECK-NOT: clc
|
|
32 ; CHECK: brasl %r14, memcmp
|
|
33 ; CHECK: br %r14
|
|
34 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 3) nobuiltin
|
|
35 %cmp = icmp eq i32 %res, 0
|
|
36 br i1 %cmp, label %exit, label %store
|
|
37
|
|
38 store:
|
|
39 store i32 0, i32 *%dest
|
|
40 br label %exit
|
|
41
|
|
42 exit:
|
|
43 ret void
|
|
44 }
|
|
45
|
|
46 ; Check a case where the result is tested for inequality.
|
|
47 define void @f4(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
48 ; CHECK-LABEL: f4:
|
|
49 ; CHECK-NOT: clc
|
|
50 ; CHECK: brasl %r14, memcmp
|
|
51 ; CHECK: br %r14
|
|
52 entry:
|
|
53 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 4) nobuiltin
|
|
54 %cmp = icmp ne i32 %res, 0
|
|
55 br i1 %cmp, label %exit, label %store
|
|
56
|
|
57 store:
|
|
58 store i32 0, i32 *%dest
|
|
59 br label %exit
|
|
60
|
|
61 exit:
|
|
62 ret void
|
|
63 }
|
|
64
|
|
65 ; Check a case where the result is tested via slt.
|
|
66 define void @f5(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
67 ; CHECK-LABEL: f5:
|
|
68 ; CHECK-NOT: clc
|
|
69 ; CHECK: brasl %r14, memcmp
|
|
70 ; CHECK: br %r14
|
|
71 entry:
|
|
72 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 5) nobuiltin
|
|
73 %cmp = icmp slt i32 %res, 0
|
|
74 br i1 %cmp, label %exit, label %store
|
|
75
|
|
76 store:
|
|
77 store i32 0, i32 *%dest
|
|
78 br label %exit
|
|
79
|
|
80 exit:
|
|
81 ret void
|
|
82 }
|
|
83
|
|
84 ; Check a case where the result is tested for sgt.
|
|
85 define void @f6(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
86 ; CHECK-LABEL: f6:
|
|
87 ; CHECK-NOT: clc
|
|
88 ; CHECK: brasl %r14, memcmp
|
|
89 ; CHECK: br %r14
|
|
90 entry:
|
|
91 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 6) nobuiltin
|
|
92 %cmp = icmp sgt i32 %res, 0
|
|
93 br i1 %cmp, label %exit, label %store
|
|
94
|
|
95 store:
|
|
96 store i32 0, i32 *%dest
|
|
97 br label %exit
|
|
98
|
|
99 exit:
|
|
100 ret void
|
|
101 }
|
|
102
|
|
103 ; Check the upper end of the CLC range. Here the result is used both as
|
|
104 ; an integer and for branching.
|
|
105 define i32 @f7(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
106 ; CHECK-LABEL: f7:
|
|
107 ; CHECK-NOT: clc
|
|
108 ; CHECK: brasl %r14, memcmp
|
|
109 ; CHECK: br %r14
|
|
110 entry:
|
|
111 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 256) nobuiltin
|
|
112 %cmp = icmp slt i32 %res, 0
|
|
113 br i1 %cmp, label %exit, label %store
|
|
114
|
|
115 store:
|
|
116 store i32 0, i32 *%dest
|
|
117 br label %exit
|
|
118
|
|
119 exit:
|
|
120 ret i32 %res
|
|
121 }
|
|
122
|
|
123 ; 257 bytes needs two CLCs.
|
|
124 define i32 @f8(i8 *%src1, i8 *%src2) {
|
|
125 ; CHECK-LABEL: f8:
|
|
126 ; CHECK-NOT: clc
|
|
127 ; CHECK: brasl %r14, memcmp
|
|
128 ; CHECK: br %r14
|
|
129 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin
|
|
130 ret i32 %res
|
|
131 }
|
|
132
|
|
133 ; Test a comparison of 258 bytes in which the CC result can be used directly.
|
|
134 define void @f9(i8 *%src1, i8 *%src2, i32 *%dest) {
|
|
135 ; CHECK-LABEL: f9:
|
|
136 ; CHECK-NOT: clc
|
|
137 ; CHECK: brasl %r14, memcmp
|
|
138 ; CHECK: br %r14
|
|
139 entry:
|
|
140 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin
|
|
141 %cmp = icmp slt i32 %res, 0
|
|
142 br i1 %cmp, label %exit, label %store
|
|
143
|
|
144 store:
|
|
145 store i32 0, i32 *%dest
|
|
146 br label %exit
|
|
147
|
|
148 exit:
|
|
149 ret void
|
|
150 }
|
|
151
|
|
152 ; Test the largest size that can use two CLCs.
|
|
153 define i32 @f10(i8 *%src1, i8 *%src2) {
|
|
154 ; CHECK-LABEL: f10:
|
|
155 ; CHECK-NOT: clc
|
|
156 ; CHECK: brasl %r14, memcmp
|
|
157 ; CHECK: br %r14
|
|
158 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 512) nobuiltin
|
|
159 ret i32 %res
|
|
160 }
|
|
161
|
|
162 ; Test the smallest size that needs 3 CLCs.
|
|
163 define i32 @f11(i8 *%src1, i8 *%src2) {
|
|
164 ; CHECK-LABEL: f11:
|
|
165 ; CHECK-NOT: clc
|
|
166 ; CHECK: brasl %r14, memcmp
|
|
167 ; CHECK: br %r14
|
|
168 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 513) nobuiltin
|
|
169 ret i32 %res
|
|
170 }
|
|
171
|
|
172 ; Test the largest size than can use 3 CLCs.
|
|
173 define i32 @f12(i8 *%src1, i8 *%src2) {
|
|
174 ; CHECK-LABEL: f12:
|
|
175 ; CHECK-NOT: clc
|
|
176 ; CHECK: brasl %r14, memcmp
|
|
177 ; CHECK: br %r14
|
|
178 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 768) nobuiltin
|
|
179 ret i32 %res
|
|
180 }
|
|
181
|
|
182 ; The next size up uses a loop instead. We leave the more complicated
|
|
183 ; loop tests to memcpy-01.ll, which shares the same form.
|
|
184 define i32 @f13(i8 *%src1, i8 *%src2) {
|
|
185 ; CHECK-LABEL: f13:
|
|
186 ; CHECK-NOT: clc
|
|
187 ; CHECK: brasl %r14, memcmp
|
|
188 ; CHECK: br %r14
|
|
189 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 769) nobuiltin
|
|
190 ret i32 %res
|
|
191 }
|