1; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -mcpu=pwr9 \
2; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s
3define dso_local void @test(i32* %Arr, i32 signext %Len) {
4; CHECK-LABEL: test:
5; CHECK:         lxvx [[REG:vs[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}
6; CHECK-NOT:     [[REG]]
7; CHECK:         xxbrw vs{{[0-9]+}}, [[REG]]
8entry:
9  %cmp1 = icmp slt i32 0, %Len
10  br i1 %cmp1, label %for.body.lr.ph, label %for.cond.cleanup
11
12for.body.lr.ph:                                   ; preds = %entry
13  %min.iters.check = icmp ult i32 %Len, 4
14  br i1 %min.iters.check, label %scalar.ph, label %vector.ph
15
16vector.ph:                                        ; preds = %for.body.lr.ph
17  %n.mod.vf = urem i32 %Len, 4
18  %n.vec = sub i32 %Len, %n.mod.vf
19  br label %vector.body
20
21vector.body:                                      ; preds = %vector.body, %vector.ph
22  %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
23  %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %index, i32 0
24  %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
25  %induction = add <4 x i32> %broadcast.splat, <i32 0, i32 1, i32 2, i32 3>
26  %0 = add i32 %index, 0
27  %1 = sext i32 %0 to i64
28  %2 = getelementptr inbounds i32, i32* %Arr, i64 %1
29  %3 = getelementptr inbounds i32, i32* %2, i32 0
30  %4 = bitcast i32* %3 to <4 x i32>*
31  %wide.load = load <4 x i32>, <4 x i32>* %4, align 4
32  %5 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %wide.load)
33  %6 = sext i32 %0 to i64
34  %7 = getelementptr inbounds i32, i32* %Arr, i64 %6
35  %8 = getelementptr inbounds i32, i32* %7, i32 0
36  %9 = bitcast i32* %8 to <4 x i32>*
37  store <4 x i32> %5, <4 x i32>* %9, align 4
38  %index.next = add i32 %index, 4
39  %10 = icmp eq i32 %index.next, %n.vec
40  br i1 %10, label %middle.block, label %vector.body
41
42middle.block:                                     ; preds = %vector.body
43  %cmp.n = icmp eq i32 %Len, %n.vec
44  br i1 %cmp.n, label %for.cond.for.cond.cleanup_crit_edge, label %scalar.ph
45
46scalar.ph:                                        ; preds = %middle.block, %for.body.lr.ph
47  %bc.resume.val = phi i32 [ %n.vec, %middle.block ], [ 0, %for.body.lr.ph ]
48  br label %for.body
49
50for.cond.for.cond.cleanup_crit_edge:              ; preds = %middle.block, %for.inc
51  br label %for.cond.cleanup
52
53for.cond.cleanup:                                 ; preds = %for.cond.for.cond.cleanup_crit_edge, %entry
54  br label %for.end
55
56for.body:                                         ; preds = %for.inc, %scalar.ph
57  %i.02 = phi i32 [ %bc.resume.val, %scalar.ph ], [ %inc, %for.inc ]
58  %idxprom = sext i32 %i.02 to i64
59  %arrayidx = getelementptr inbounds i32, i32* %Arr, i64 %idxprom
60  %11 = load i32, i32* %arrayidx, align 4
61  %12 = call i32 @llvm.bswap.i32(i32 %11)
62  %idxprom1 = sext i32 %i.02 to i64
63  %arrayidx2 = getelementptr inbounds i32, i32* %Arr, i64 %idxprom1
64  store i32 %12, i32* %arrayidx2, align 4
65  br label %for.inc
66
67for.inc:                                          ; preds = %for.body
68  %inc = add nsw i32 %i.02, 1
69  %cmp = icmp slt i32 %inc, %Len
70  br i1 %cmp, label %for.body, label %for.cond.for.cond.cleanup_crit_edge
71
72for.end:                                          ; preds = %for.cond.cleanup
73  ret void
74}
75
76define dso_local <8 x i16> @test_halfword(<8 x i16> %a) local_unnamed_addr {
77; CHECK-LABEL: test_halfword:
78; CHECK:       xxbrh vs34, vs34
79; CHECK-NEXT:  blr
80entry:
81  %0 = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %a)
82  ret <8 x i16> %0
83}
84
85define dso_local <2 x i64> @test_doubleword(<2 x i64> %a) local_unnamed_addr {
86; CHECK-LABEL: test_doubleword:
87; CHECK:       xxbrd vs34, vs34
88; CHECK-NEXT:  blr
89entry:
90  %0 = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %a)
91  ret <2 x i64> %0
92}
93
94define dso_local <1 x i128> @test_quadword(<1 x i128> %a) local_unnamed_addr {
95; CHECK-LABEL: test_quadword:
96; CHECK:       xxbrq vs34, vs34
97; CHECK-NEXT:  blr
98entry:
99  %0 = call <1 x i128> @llvm.bswap.v1i128(<1 x i128> %a)
100  ret <1 x i128> %0
101}
102
103; Function Attrs: nounwind readnone speculatable willreturn
104declare <1 x i128> @llvm.bswap.v1i128(<1 x i128>)
105
106; Function Attrs: nounwind readnone speculatable willreturn
107declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
108
109; Function Attrs: nounwind readnone speculatable willreturn
110declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
111
112; Function Attrs: nounwind readnone speculatable willreturn
113declare i32 @llvm.bswap.i32(i32)
114
115; Function Attrs: nounwind readnone speculatable willreturn
116declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>)
117