; RUN: opt -S -dse < %s | FileCheck %s
declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
+declare void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
declare void @llvm.memmove.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i1) nounwind
-define void @test1() {
+define void @test1(i8* noalias %A, i8* noalias %B) {
; CHECK-LABEL: @test1(
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B:%.*]], i8 12, i1 false)
; CHECK-NEXT: ret void
;
- %A = alloca i8
- %B = alloca i8
-
store i8 0, i8* %A ;; Written to by memcpy
- call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
ret void
}
-define void @test2() {
+; FIXME: We should eliminate this dead store.
+define void @test2(i8* noalias %A, i8* noalias %B) {
; CHECK-LABEL: @test2(
+; CHECK-NEXT: store i8 0, i8* [[A:%.*]], align 1
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A]], i8* [[B:%.*]], i8 12, i1 false)
; CHECK-NEXT: ret void
;
- %A = alloca i8
- %B = alloca i8
+ store i8 0, i8* %A ;; Written to by memmove
+
+ call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
+ ret void
+}
+
+define void @test2a(i8* %A, i8* %B) {
+; CHECK-LABEL: @test2a(
+; CHECK-NEXT: store i8 0, i8* [[A:%.*]], align 1
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A]], i8* [[B:%.*]], i8 12, i1 false)
+; CHECK-NEXT: ret void
+;
store i8 0, i8* %A ;; Written to by memmove
- call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false)
+ call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
ret void
}
-define void @test3() {
+define void @test3(i8* noalias %A) {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
+; CHECK-NEXT: call void @llvm.memset.p0i8.i8(i8* [[A:%.*]], i8 0, i8 12, i1 false)
; CHECK-NEXT: ret void
;
- %A = alloca i8
- %B = alloca i8
-
store i8 0, i8* %A ;; Written to by memset
- call void @llvm.memset.p0i8.i8(i8* %A, i8 0, i8 -1, i1 false)
+ call void @llvm.memset.p0i8.i8(i8* %A, i8 0, i8 12, i1 false)
ret void
}
ret void
}
+
+define void @test7(i8* noalias %A, i8* noalias %B) {
+; CHECK-LABEL: @test7(
+; CHECK-NEXT: call void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B:%.*]], i8 12, i1 false)
+; CHECK-NEXT: ret void
+;
+ store i8 0, i8* %A ;; Written to by memcpy
+
+ call void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
+
+ ret void
+}
}
define void @test_memset_memcpy_inline(i8* noalias %P, i8* noalias %Q) {
+; CHECK-LABEL: @test_memset_memcpy_inline(
+; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
+; CHECK-NEXT: ret void
+;
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
- ret void
+ ret void
}
define void @test_store_memcpy_inline(i8* noalias %P, i8* noalias %Q) {
+; CHECK-LABEL: @test_store_memcpy_inline(
+; CHECK-NEXT: [[P_4:%.*]] = getelementptr i8, i8* [[P:%.*]], i64 4
+; CHECK-NEXT: store i8 4, i8* [[P_4]], align 1
+; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q:%.*]], i64 4, i1 false)
+; CHECK-NEXT: ret void
+;
store i8 0, i8* %P
%P.1 = getelementptr i8, i8* %P, i64 1
store i8 1, i8* %P.1
%P.4 = getelementptr i8, i8* %P, i64 4
store i8 4, i8* %P.4
tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 4, i1 false)
- ret void
+ ret void
}
declare void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64 immarg, i1 immarg)