1; RUN: llc -verify-machineinstrs -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
2
3; This code causes an assertion failure if dereferenceable flag is not properly set in the load generated for memcpy
4
5; CHECK-LABEL: @func
6; CHECK: lxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
7; CHECK-NOT: lxvd2x
8; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
9; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
10; CHECK: blr
11
12define void @func(i1 %flag) {
13entry:
14  %pairs = alloca [4 x <2 x i64>], align 8
15  %pair1 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 1
16  %pair2 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 2
17  %pvec1 = bitcast <2 x i64>* %pair1 to <2 x i64>*
18  %pvec2 = bitcast <2 x i64>* %pair2 to <2 x i64>*
19  %dst = bitcast [4 x <2 x i64>]* %pairs to i8*
20  %src = bitcast <2 x i64>* %pair2 to i8*
21  br i1 %flag, label %end, label %dummy
22
23end:
24  ; copy third element into first element by memcpy
25  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 nonnull %dst, i8* align 8 %src, i64 16, i1 false)
26  ; copy third element into second element by LD/ST
27  %vec2 = load <2 x i64>, <2 x i64>* %pvec2, align 8
28  store <2 x i64> %vec2, <2 x i64>* %pvec1, align 8
29  ret void
30
31dummy:
32  ; to make use of %src in another BB
33  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %src, i8* %src, i64 0, i1 false)
34  br label %end
35}
36
37
38; CHECK-LABEL: @func2
39; CHECK: lxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
40; CHECK-NOT: lxvd2x
41; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
42; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
43; CHECK: blr
44
45define void @func2(i1 %flag) {
46entry:
47  %pairs = alloca [4 x <2 x i64>], align 8
48  %pair1 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 1
49  %pair2 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 2
50  %pvec1 = bitcast <2 x i64>* %pair1 to <2 x i64>*
51  %pvec2 = bitcast <2 x i64>* %pair2 to <2 x i64>*
52  %dst = bitcast [4 x <2 x i64>]* %pairs to i8*
53  %src = bitcast <2 x i64>* %pair2 to i8*
54  br i1 %flag, label %end, label %dummy
55
56end:
57  ; copy third element into first element by memcpy
58  call void @llvm.memmove.p0i8.p0i8.i64(i8* align 8 nonnull %dst, i8* align 8 %src, i64 16, i1 false)
59  ; copy third element into second element by LD/ST
60  %vec2 = load <2 x i64>, <2 x i64>* %pvec2, align 8
61  store <2 x i64> %vec2, <2 x i64>* %pvec1, align 8
62  ret void
63
64dummy:
65  ; to make use of %src in another BB
66  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %src, i8* %src, i64 0, i1 false)
67  br label %end
68}
69
70; Function Attrs: argmemonly nounwind
71declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #1
72declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #1
73
74attributes #1 = { argmemonly nounwind }
75