1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs | FileCheck %s
3
4@CVal = external local_unnamed_addr global i8, align 1
5@SVal = external local_unnamed_addr global i16, align 2
6@IVal = external local_unnamed_addr global i32, align 4
7@LVal = external local_unnamed_addr global i64, align 8
8@USVal = external local_unnamed_addr global i16, align 2
9@arr = external local_unnamed_addr global i64*, align 8
10@arri = external local_unnamed_addr global i32*, align 8
11
12; Test the same constant can be used by different stores.
13
14%struct.S = type { i64, i8, i16, i32 }
15
16define void @foo(%struct.S* %p) {
17; CHECK-LABEL: foo:
18; CHECK:       # %bb.0:
19; CHECK-NEXT:    li 4, 0
20; CHECK-NEXT:    stb 4, 8(3)
21; CHECK-NEXT:    std 4, 0(3)
22; CHECK-NEXT:    sth 4, 10(3)
23; CHECK-NEXT:    stw 4, 12(3)
24; CHECK-NEXT:    blr
25  %l4 = bitcast %struct.S* %p to i64*
26  store i64 0, i64* %l4, align 8
27  %c = getelementptr %struct.S, %struct.S* %p, i64 0, i32 1
28  store i8 0, i8* %c, align 8
29  %s = getelementptr %struct.S, %struct.S* %p, i64 0, i32 2
30  store i16 0, i16* %s, align 2
31  %i = getelementptr %struct.S, %struct.S* %p, i64 0, i32 3
32  store i32 0, i32* %i, align 4
33  ret void
34
35}
36
37define void @bar(%struct.S* %p) {
38; CHECK-LABEL: bar:
39; CHECK:       # %bb.0:
40; CHECK-NEXT:    li 4, 2
41; CHECK-NEXT:    stw 4, 12(3)
42; CHECK-NEXT:    sth 4, 10(3)
43; CHECK-NEXT:    std 4, 0(3)
44; CHECK-NEXT:    stb 4, 8(3)
45; CHECK-NEXT:    blr
46  %i = getelementptr %struct.S, %struct.S* %p, i64 0, i32 3
47  store i32 2, i32* %i, align 4
48  %s = getelementptr %struct.S, %struct.S* %p, i64 0, i32 2
49  store i16 2, i16* %s, align 2
50  %c = getelementptr %struct.S, %struct.S* %p, i64 0, i32 1
51  store i8 2, i8* %c, align 8
52  %l4 = bitcast %struct.S* %p to i64*
53  store i64 2, i64* %l4, align 8
54  ret void
55
56}
57
58; Function Attrs: norecurse nounwind
59define void @setSmallNeg() {
60; CHECK-LABEL: setSmallNeg:
61; CHECK:       # %bb.0: # %entry
62; CHECK-NEXT:    addis 3, 2, .LC0@toc@ha
63; CHECK-NEXT:    addis 4, 2, .LC1@toc@ha
64; CHECK-NEXT:    addis 5, 2, .LC2@toc@ha
65; CHECK-NEXT:    addis 6, 2, .LC3@toc@ha
66; CHECK-NEXT:    li 7, -7
67; CHECK-NEXT:    ld 3, .LC0@toc@l(3)
68; CHECK-NEXT:    ld 4, .LC1@toc@l(4)
69; CHECK-NEXT:    ld 5, .LC2@toc@l(5)
70; CHECK-NEXT:    ld 6, .LC3@toc@l(6)
71; CHECK-NEXT:    stb 7, 0(3)
72; CHECK-NEXT:    sth 7, 0(4)
73; CHECK-NEXT:    std 7, 0(6)
74; CHECK-NEXT:    stw 7, 0(5)
75; CHECK-NEXT:    blr
76entry:
77  store i8 -7, i8* @CVal, align 1
78  store i16 -7, i16* @SVal, align 2
79  store i32 -7, i32* @IVal, align 4
80  store i64 -7, i64* @LVal, align 8
81  ret void
82}
83
84; Function Attrs: norecurse nounwind
85define void @setSmallPos() {
86; CHECK-LABEL: setSmallPos:
87; CHECK:       # %bb.0: # %entry
88; CHECK-NEXT:    addis 3, 2, .LC0@toc@ha
89; CHECK-NEXT:    addis 4, 2, .LC1@toc@ha
90; CHECK-NEXT:    addis 5, 2, .LC2@toc@ha
91; CHECK-NEXT:    addis 6, 2, .LC3@toc@ha
92; CHECK-NEXT:    li 7, 8
93; CHECK-NEXT:    ld 3, .LC0@toc@l(3)
94; CHECK-NEXT:    ld 4, .LC1@toc@l(4)
95; CHECK-NEXT:    ld 5, .LC2@toc@l(5)
96; CHECK-NEXT:    ld 6, .LC3@toc@l(6)
97; CHECK-NEXT:    stb 7, 0(3)
98; CHECK-NEXT:    sth 7, 0(4)
99; CHECK-NEXT:    std 7, 0(6)
100; CHECK-NEXT:    stw 7, 0(5)
101; CHECK-NEXT:    blr
102entry:
103  store i8 8, i8* @CVal, align 1
104  store i16 8, i16* @SVal, align 2
105  store i32 8, i32* @IVal, align 4
106  store i64 8, i64* @LVal, align 8
107  ret void
108}
109
110; Function Attrs: norecurse nounwind
111define void @setMaxNeg() {
112; CHECK-LABEL: setMaxNeg:
113; CHECK:       # %bb.0: # %entry
114; CHECK-NEXT:    addis 3, 2, .LC1@toc@ha
115; CHECK-NEXT:    addis 4, 2, .LC2@toc@ha
116; CHECK-NEXT:    addis 5, 2, .LC3@toc@ha
117; CHECK-NEXT:    li 6, -32768
118; CHECK-NEXT:    ld 3, .LC1@toc@l(3)
119; CHECK-NEXT:    ld 4, .LC2@toc@l(4)
120; CHECK-NEXT:    ld 5, .LC3@toc@l(5)
121; CHECK-NEXT:    sth 6, 0(3)
122; CHECK-NEXT:    stw 6, 0(4)
123; CHECK-NEXT:    std 6, 0(5)
124; CHECK-NEXT:    blr
125entry:
126  store i16 -32768, i16* @SVal, align 2
127  store i32 -32768, i32* @IVal, align 4
128  store i64 -32768, i64* @LVal, align 8
129  ret void
130}
131
132; Function Attrs: norecurse nounwind
133define void @setMaxPos() {
134; CHECK-LABEL: setMaxPos:
135; CHECK:       # %bb.0: # %entry
136; CHECK-NEXT:    addis 3, 2, .LC1@toc@ha
137; CHECK-NEXT:    addis 4, 2, .LC2@toc@ha
138; CHECK-NEXT:    addis 5, 2, .LC3@toc@ha
139; CHECK-NEXT:    li 6, 32767
140; CHECK-NEXT:    ld 3, .LC1@toc@l(3)
141; CHECK-NEXT:    ld 4, .LC2@toc@l(4)
142; CHECK-NEXT:    ld 5, .LC3@toc@l(5)
143; CHECK-NEXT:    sth 6, 0(3)
144; CHECK-NEXT:    stw 6, 0(4)
145; CHECK-NEXT:    std 6, 0(5)
146; CHECK-NEXT:    blr
147entry:
148  store i16 32767, i16* @SVal, align 2
149  store i32 32767, i32* @IVal, align 4
150  store i64 32767, i64* @LVal, align 8
151  ret void
152}
153
154; Function Attrs: norecurse nounwind
155define void @setExcessiveNeg() {
156; CHECK-LABEL: setExcessiveNeg:
157; CHECK:       # %bb.0: # %entry
158; CHECK-NEXT:    addis 3, 2, .LC2@toc@ha
159; CHECK-NEXT:    addis 4, 2, .LC3@toc@ha
160; CHECK-NEXT:    lis 5, -1
161; CHECK-NEXT:    ld 3, .LC2@toc@l(3)
162; CHECK-NEXT:    ld 4, .LC3@toc@l(4)
163; CHECK-NEXT:    ori 5, 5, 32767
164; CHECK-NEXT:    stw 5, 0(3)
165; CHECK-NEXT:    std 5, 0(4)
166; CHECK-NEXT:    blr
167entry:
168  store i32 -32769, i32* @IVal, align 4
169  store i64 -32769, i64* @LVal, align 8
170  ret void
171}
172
173; Function Attrs: norecurse nounwind
174define void @setExcessivePos() {
175; CHECK-LABEL: setExcessivePos:
176; CHECK:       # %bb.0: # %entry
177; CHECK-NEXT:    addis 3, 2, .LC4@toc@ha
178; CHECK-NEXT:    addis 4, 2, .LC2@toc@ha
179; CHECK-NEXT:    addis 5, 2, .LC3@toc@ha
180; CHECK-NEXT:    li 6, 0
181; CHECK-NEXT:    ld 3, .LC4@toc@l(3)
182; CHECK-NEXT:    ld 4, .LC2@toc@l(4)
183; CHECK-NEXT:    ld 5, .LC3@toc@l(5)
184; CHECK-NEXT:    ori 6, 6, 32768
185; CHECK-NEXT:    sth 6, 0(3)
186; CHECK-NEXT:    stw 6, 0(4)
187; CHECK-NEXT:    std 6, 0(5)
188; CHECK-NEXT:    blr
189entry:
190  store i16 -32768, i16* @USVal, align 2
191  store i32 32768, i32* @IVal, align 4
192  store i64 32768, i64* @LVal, align 8
193  ret void
194}
195
196define void @SetArr(i32 signext %Len) {
197; CHECK-LABEL: SetArr:
198; CHECK:       # %bb.0: # %entry
199; CHECK-NEXT:    cmpwi 3, 1
200; CHECK-NEXT:    bltlr 0
201; CHECK-NEXT:  # %bb.1: # %for.body.lr.ph
202; CHECK-NEXT:    addis 4, 2, .LC5@toc@ha
203; CHECK-NEXT:    addis 5, 2, .LC6@toc@ha
204; CHECK-NEXT:    clrldi 6, 3, 32
205; CHECK-NEXT:    ld 4, .LC5@toc@l(4)
206; CHECK-NEXT:    ld 5, .LC6@toc@l(5)
207; CHECK-NEXT:    ld 4, 0(4)
208; CHECK-NEXT:    ld 5, 0(5)
209; CHECK-NEXT:    mtctr 6
210; CHECK-NEXT:    addi 3, 4, -8
211; CHECK-NEXT:    addi 4, 5, -4
212; CHECK-NEXT:    li 5, -7
213; CHECK-NEXT:    .p2align 4
214; CHECK-NEXT:  .LBB8_2: # %for.body
215; CHECK-NEXT:    #
216; CHECK-NEXT:    stdu 5, 8(3)
217; CHECK-NEXT:    stwu 5, 4(4)
218; CHECK-NEXT:    bdnz .LBB8_2
219; CHECK-NEXT:  # %bb.3: # %for.cond.cleanup
220; CHECK-NEXT:    blr
221entry:
222  %cmp7 = icmp sgt i32 %Len, 0
223  br i1 %cmp7, label %for.body.lr.ph, label %for.cond.cleanup
224
225for.body.lr.ph:                                   ; preds = %entry
226  %0 = load i64*, i64** @arr, align 8
227  %1 = load i32*, i32** @arri, align 8
228  %wide.trip.count = zext i32 %Len to i64
229  br label %for.body
230
231for.cond.cleanup:                                 ; preds = %for.body, %entry
232  ret void
233
234for.body:                                         ; preds = %for.body, %for.body.lr.ph
235  %indvars.iv = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next, %for.body ]
236  %arrayidx = getelementptr inbounds i64, i64* %0, i64 %indvars.iv
237  store i64 -7, i64* %arrayidx, align 8
238  %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
239  store i32 -7, i32* %arrayidx2, align 4
240  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
241  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
242  br i1 %exitcond, label %for.cond.cleanup, label %for.body
243}
244
245define void @setSameValDiffSizeCI() {
246; CHECK-LABEL: setSameValDiffSizeCI:
247; CHECK:       # %bb.0: # %entry
248; CHECK-NEXT:    addis 3, 2, .LC2@toc@ha
249; CHECK-NEXT:    addis 4, 2, .LC0@toc@ha
250; CHECK-NEXT:    li 5, 255
251; CHECK-NEXT:    ld 3, .LC2@toc@l(3)
252; CHECK-NEXT:    ld 4, .LC0@toc@l(4)
253; CHECK-NEXT:    stw 5, 0(3)
254; CHECK-NEXT:    stb 5, 0(4)
255; CHECK-NEXT:    blr
256entry:
257  store i32 255, i32* @IVal, align 4
258  store i8 -1, i8* @CVal, align 1
259  ret void
260}
261
262define void @setSameValDiffSizeSI() {
263; CHECK-LABEL: setSameValDiffSizeSI:
264; CHECK:       # %bb.0: # %entry
265; CHECK-NEXT:    addis 3, 2, .LC2@toc@ha
266; CHECK-NEXT:    addis 4, 2, .LC1@toc@ha
267; CHECK-NEXT:    li 5, 0
268; CHECK-NEXT:    ld 3, .LC2@toc@l(3)
269; CHECK-NEXT:    ld 4, .LC1@toc@l(4)
270; CHECK-NEXT:    ori 5, 5, 65535
271; CHECK-NEXT:    stw 5, 0(3)
272; CHECK-NEXT:    sth 5, 0(4)
273; CHECK-NEXT:    blr
274entry:
275  store i32 65535, i32* @IVal, align 4
276  store i16 -1, i16* @SVal, align 2
277  ret void
278}
279