1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; Test memset 0 with variable length
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
6 define void @fun0(ptr %Addr, i64 %Len) {
9 ; CHECK-NEXT: aghi %r3, -1
10 ; CHECK-NEXT: cgibe %r3, -1, 0(%r14)
11 ; CHECK-NEXT: .LBB0_1:
12 ; CHECK-NEXT: srlg %r0, %r3, 8
13 ; CHECK-NEXT: cgije %r0, 0, .LBB0_3
14 ; CHECK-NEXT: .LBB0_2: # =>This Inner Loop Header: Depth=1
15 ; CHECK-NEXT: xc 0(256,%r2), 0(%r2)
16 ; CHECK-NEXT: la %r2, 256(%r2)
17 ; CHECK-NEXT: brctg %r0, .LBB0_2
18 ; CHECK-NEXT: .LBB0_3:
19 ; CHECK-NEXT: exrl %r3, .Ltmp0
21 tail call void @llvm.memset.p0.i64(ptr %Addr, i8 0, i64 %Len, i1 false)
25 define void @fun1(ptr %Addr, i32 %Len) {
28 ; CHECK-NEXT: llgfr %r1, %r3
29 ; CHECK-NEXT: aghi %r1, -1
30 ; CHECK-NEXT: cgibe %r1, -1, 0(%r14)
31 ; CHECK-NEXT: .LBB1_1:
32 ; CHECK-NEXT: srlg %r0, %r1, 8
33 ; CHECK-NEXT: cgije %r0, 0, .LBB1_3
34 ; CHECK-NEXT: .LBB1_2: # =>This Inner Loop Header: Depth=1
35 ; CHECK-NEXT: xc 0(256,%r2), 0(%r2)
36 ; CHECK-NEXT: la %r2, 256(%r2)
37 ; CHECK-NEXT: brctg %r0, .LBB1_2
38 ; CHECK-NEXT: .LBB1_3:
39 ; CHECK-NEXT: exrl %r1, .Ltmp0
41 tail call void @llvm.memset.p0.i32(ptr %Addr, i8 0, i32 %Len, i1 false)
45 ; Test that identical target instructions get reused.
46 define void @fun2(ptr %Addr, i32 %Len) {
49 ; CHECK-NEXT: llgfr %r1, %r3
50 ; CHECK-NEXT: aghi %r1, -1
51 ; CHECK-NEXT: cgije %r1, -1, .LBB2_4
52 ; CHECK-NEXT: # %bb.1:
53 ; CHECK-NEXT: srlg %r0, %r1, 8
54 ; CHECK-NEXT: lgr %r3, %r2
55 ; CHECK-NEXT: cgije %r0, 0, .LBB2_3
56 ; CHECK-NEXT: .LBB2_2: # =>This Inner Loop Header: Depth=1
57 ; CHECK-NEXT: xc 0(256,%r3), 0(%r3)
58 ; CHECK-NEXT: la %r3, 256(%r3)
59 ; CHECK-NEXT: brctg %r0, .LBB2_2
60 ; CHECK-NEXT: .LBB2_3:
61 ; CHECK-NEXT: exrl %r1, .Ltmp1
62 ; CHECK-NEXT: .LBB2_4:
63 ; CHECK-NEXT: cgije %r1, -1, .LBB2_8
64 ; CHECK-NEXT: # %bb.5:
65 ; CHECK-NEXT: srlg %r0, %r1, 8
66 ; CHECK-NEXT: lgr %r3, %r2
67 ; CHECK-NEXT: cgije %r0, 0, .LBB2_7
68 ; CHECK-NEXT: .LBB2_6: # =>This Inner Loop Header: Depth=1
69 ; CHECK-NEXT: xc 0(256,%r3), 0(%r3)
70 ; CHECK-NEXT: la %r3, 256(%r3)
71 ; CHECK-NEXT: brctg %r0, .LBB2_6
72 ; CHECK-NEXT: .LBB2_7:
73 ; CHECK-NEXT: exrl %r1, .Ltmp1
74 ; CHECK-NEXT: .LBB2_8:
75 ; CHECK-NEXT: cgibe %r1, -1, 0(%r14)
76 ; CHECK-NEXT: .LBB2_9:
77 ; CHECK-NEXT: srlg %r0, %r1, 8
78 ; CHECK-NEXT: cgije %r0, 0, .LBB2_11
79 ; CHECK-NEXT: .LBB2_10: # =>This Inner Loop Header: Depth=1
80 ; CHECK-NEXT: xc 0(256,%r2), 0(%r2)
81 ; CHECK-NEXT: la %r2, 256(%r2)
82 ; CHECK-NEXT: brctg %r0, .LBB2_10
83 ; CHECK-NEXT: .LBB2_11:
84 ; CHECK-NEXT: exrl %r1, .Ltmp0
86 tail call void @llvm.memset.p0.i32(ptr %Addr, i8 0, i32 %Len, i1 false)
87 tail call void @llvm.memset.p0.i32(ptr %Addr, i8 0, i32 %Len, i1 false)
88 tail call void @llvm.memset.p0.i32(ptr %Addr, i8 0, i32 %Len, i1 false)
92 ; Test that a memset to nullptr compiles.
93 define void @fun3(i64 %Len) {
96 ; CHECK-NEXT: aghi %r2, -1
97 ; CHECK-NEXT: cgibe %r2, -1, 0(%r14)
98 ; CHECK-NEXT: .LBB3_1:
99 ; CHECK-NEXT: srlg %r0, %r2, 8
100 ; CHECK-NEXT: lghi %r1, 0
101 ; CHECK-NEXT: cgije %r0, 0, .LBB3_3
102 ; CHECK-NEXT: .LBB3_2: # =>This Inner Loop Header: Depth=1
103 ; CHECK-NEXT: xc 0(256,%r1), 0(%r1)
104 ; CHECK-NEXT: la %r1, 256(%r1)
105 ; CHECK-NEXT: brctg %r0, .LBB3_2
106 ; CHECK-NEXT: .LBB3_3:
107 ; CHECK-NEXT: exrl %r2, .Ltmp2
108 ; CHECK-NEXT: br %r14
109 call void @llvm.memset.p0.i64(ptr null, i8 0, i64 %Len, i1 false)
113 ; Test that a memset with a length argument that DAGCombiner will convert
114 ; into a constant get the correct number of bytes set.
115 @Data = external hidden constant [1024 x i8], align 2
116 define void @fun4() {
119 ; CHECK-NEXT: larl %r1, Data
120 ; CHECK-NEXT: xc 35(256,%r1), 35(%r1)
121 ; CHECK-NEXT: xc 291(256,%r1), 291(%r1)
122 ; CHECK-NEXT: xc 547(256,%r1), 547(%r1)
123 ; CHECK-NEXT: xc 803(221,%r1), 803(%r1)
124 ; CHECK-NEXT: mvghi 0(%r1), 989
125 ; CHECK-NEXT: br %r14
126 call void @llvm.memset.p0.i64(
127 ptr getelementptr inbounds ([1024 x i8], ptr @Data, i64 0, i64 35),
129 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
130 ptr @Data, i64 1, i64 0) to i64), i64 1),
131 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
132 ptr @Data, i64 0, i64 35) to i64), i64 1)),
134 %i11 = getelementptr i8, ptr null,
135 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
136 ptr @Data, i64 1, i64 0) to i64), i64 1),
137 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
138 ptr @Data, i64 0, i64 35) to i64), i64 1))
139 store ptr %i11, ptr undef, align 8
143 ; The same, with a resulting constant length of 0.
144 define void @fun5() {
147 ; CHECK-NEXT: mvghi 0(%r1), 0
148 ; CHECK-NEXT: br %r14
149 call void @llvm.memset.p0.i64(
150 ptr getelementptr inbounds ([1024 x i8], ptr @Data, i64 0, i64 35),
152 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
153 ptr @Data, i64 1, i64 35) to i64), i64 1),
154 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
155 ptr @Data, i64 1, i64 35) to i64), i64 1)),
157 %i11 = getelementptr i8, ptr null,
158 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
159 ptr @Data, i64 1, i64 35) to i64), i64 1),
160 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
161 ptr @Data, i64 1, i64 35) to i64), i64 1))
162 store ptr %i11, ptr undef, align 8
166 ; The same, with a resulting constant length of 1.
167 define void @fun6() {
170 ; CHECK-NEXT: larl %r1, Data
171 ; CHECK-NEXT: xc 35(1,%r1), 35(%r1)
172 ; CHECK-NEXT: mvghi 0(%r1), 1
173 ; CHECK-NEXT: br %r14
174 call void @llvm.memset.p0.i64(
175 ptr getelementptr inbounds ([1024 x i8], ptr @Data, i64 0, i64 35),
177 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
178 ptr @Data, i64 1, i64 36) to i64), i64 1),
179 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
180 ptr @Data, i64 1, i64 35) to i64), i64 1)),
182 %i11 = getelementptr i8, ptr null,
183 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
184 ptr @Data, i64 1, i64 36) to i64), i64 1),
185 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
186 ptr @Data, i64 1, i64 35) to i64), i64 1))
187 store ptr %i11, ptr undef, align 8
191 ; The same, with a resulting constant length of 256.
192 define void @fun7() {
195 ; CHECK-NEXT: larl %r1, Data
196 ; CHECK-NEXT: xc 35(256,%r1), 35(%r1)
197 ; CHECK-NEXT: mvghi 0(%r1), 256
198 ; CHECK-NEXT: br %r14
199 call void @llvm.memset.p0.i64(
200 ptr getelementptr inbounds ([1024 x i8], ptr @Data, i64 0, i64 35),
202 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
203 ptr @Data, i64 1, i64 291) to i64), i64 1),
204 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
205 ptr @Data, i64 1, i64 35) to i64), i64 1)),
207 %i11 = getelementptr i8, ptr null,
208 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
209 ptr @Data, i64 1, i64 291) to i64), i64 1),
210 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
211 ptr @Data, i64 1, i64 35) to i64), i64 1))
212 store ptr %i11, ptr undef, align 8
216 ; The same, with a resulting constant length of 257.
217 define void @fun8() {
220 ; CHECK-NEXT: larl %r1, Data
221 ; CHECK-NEXT: xc 35(256,%r1), 35(%r1)
222 ; CHECK-NEXT: xc 291(1,%r1), 291(%r1)
223 ; CHECK-NEXT: mvghi 0(%r1), 257
224 ; CHECK-NEXT: br %r14
225 call void @llvm.memset.p0.i64(
226 ptr getelementptr inbounds ([1024 x i8], ptr @Data, i64 0, i64 35),
228 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
229 ptr @Data, i64 1, i64 292) to i64), i64 1),
230 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
231 ptr @Data, i64 1, i64 35) to i64), i64 1)),
233 %i11 = getelementptr i8, ptr null,
234 i64 sub (i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
235 ptr @Data, i64 1, i64 292) to i64), i64 1),
236 i64 add (i64 ptrtoint (ptr getelementptr inbounds ([1024 x i8],
237 ptr @Data, i64 1, i64 35) to i64), i64 1))
238 store ptr %i11, ptr undef, align 8
243 ; CHECK-NEXT: xc 0(1,%r1), 0(%r1)
244 ; CHECK-NEXT: .Ltmp0:
245 ; CHECK-NEXT: xc 0(1,%r2), 0(%r2)
246 ; CHECK-NEXT: .Ltmp1:
247 ; CHECK-NEXT: xc 0(1,%r3), 0(%r3)
249 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
250 declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)