summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorHiroshi Inoue <inouehrs@jp.ibm.com>2017-06-24 15:17:38 +0000
committerHiroshi Inoue <inouehrs@jp.ibm.com>2017-06-24 15:17:38 +0000
commit95f24dca98e63f14c3ab2585cb37e76839fc120f (patch)
treeeddbdea4a23844dd96b54089e62ddbe031dbf830 /llvm/test
parent4bba4ba5bae3a18ea8cbde0e99ab2416bc0ea8e5 (diff)
downloadbcm5719-llvm-95f24dca98e63f14c3ab2585cb37e76839fc120f.tar.gz
bcm5719-llvm-95f24dca98e63f14c3ab2585cb37e76839fc120f.zip
[SelectionDAG] set dereferenceable flag when expanding memcpy/memmove
When SelectionDAG expands memcpy (or memmove) call into a sequence of load and store instructions, it disregards dereferenceable flag even the source pointer is known to be dereferenceable. This results in an assertion failure if SelectionDAG commonizes a load instruction generated for memcpy with another load instruction for the source pointer. This patch makes SelectionDAG to set the dereferenceable flag for the load instructions properly to avoid the assertion failure. Differential Revision: https://reviews.llvm.org/D34467 llvm-svn: 306209
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/PowerPC/memcpy_dereferenceable.ll74
1 files changed, 74 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/PowerPC/memcpy_dereferenceable.ll b/llvm/test/CodeGen/PowerPC/memcpy_dereferenceable.ll
new file mode 100644
index 00000000000..ed821849f09
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/memcpy_dereferenceable.ll
@@ -0,0 +1,74 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
+
+; This code causes an assertion failure if dereferenceable flag is not properly set in the load generated for memcpy
+
+; CHECK-LABEL: @func
+; CHECK: lxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK-NOT: lxvd2x
+; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK: blr
+
+define void @func(i1 %flag) {
+entry:
+ %pairs = alloca [4 x <2 x i64>], align 8
+ %pair1 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 1
+ %pair2 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 2
+ %pvec1 = bitcast <2 x i64>* %pair1 to <2 x i64>*
+ %pvec2 = bitcast <2 x i64>* %pair2 to <2 x i64>*
+ %dst = bitcast [4 x <2 x i64>]* %pairs to i8*
+ %src = bitcast <2 x i64>* %pair2 to i8*
+ br i1 %flag, label %end, label %dummy
+
+end:
+ ; copy third element into first element by memcpy
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %dst, i8* %src, i64 16, i32 8, i1 false)
+ ; copy third element into second element by LD/ST
+ %vec2 = load <2 x i64>, <2 x i64>* %pvec2, align 8
+ store <2 x i64> %vec2, <2 x i64>* %pvec1, align 8
+ ret void
+
+dummy:
+ ; to make use of %src in another BB
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %src, i8* %src, i64 0, i32 0, i1 false)
+ br label %end
+}
+
+
+; CHECK-LABEL: @func2
+; CHECK: lxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK-NOT: lxvd2x
+; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK: stxvd2x [[VREG:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK: blr
+
+define void @func2(i1 %flag) {
+entry:
+ %pairs = alloca [4 x <2 x i64>], align 8
+ %pair1 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 1
+ %pair2 = getelementptr inbounds [4 x <2 x i64>], [4 x <2 x i64>]* %pairs, i64 0, i64 2
+ %pvec1 = bitcast <2 x i64>* %pair1 to <2 x i64>*
+ %pvec2 = bitcast <2 x i64>* %pair2 to <2 x i64>*
+ %dst = bitcast [4 x <2 x i64>]* %pairs to i8*
+ %src = bitcast <2 x i64>* %pair2 to i8*
+ br i1 %flag, label %end, label %dummy
+
+end:
+ ; copy third element into first element by memcpy
+ call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull %dst, i8* %src, i64 16, i32 8, i1 false)
+ ; copy third element into second element by LD/ST
+ %vec2 = load <2 x i64>, <2 x i64>* %pvec2, align 8
+ store <2 x i64> %vec2, <2 x i64>* %pvec1, align 8
+ ret void
+
+dummy:
+ ; to make use of %src in another BB
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %src, i8* %src, i64 0, i32 0, i1 false)
+ br label %end
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1
+declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1
+
+attributes #1 = { argmemonly nounwind }
OpenPOWER on IntegriCloud