[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / MemCpyOpt / memset-memcpy-to-2x-memset.ll
blobe6e74926c3e22da5b24346ff1e80a86e4bb34e63
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -memcpyopt -S %s -verify-memoryssa | FileCheck %s
4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6 define void @test(i8* %dst1, i8* %dst2, i8 %c) {
7 ; CHECK-LABEL: @test(
8 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
9 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
10 ; CHECK-NEXT:    ret void
12   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 128, i1 false)
13   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst2, i8* align 8 %dst1, i64 128, i1 false)
14   ret void
17 define void @test_smaller_memcpy(i8* %dst1, i8* %dst2, i8 %c) {
18 ; CHECK-LABEL: @test_smaller_memcpy(
19 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
20 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
21 ; CHECK-NEXT:    ret void
23   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 128, i1 false)
24   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 100, i1 false)
25   ret void
28 define void @test_smaller_memset(i8* %dst1, i8* %dst2, i8 %c) {
29 ; CHECK-LABEL: @test_smaller_memset(
30 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 100, i1 false)
31 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST2:%.*]], i8* [[DST1]], i64 128, i1 false)
32 ; CHECK-NEXT:    ret void
34   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 100, i1 false)
35   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 128, i1 false)
36   ret void
39 define void @test_align_memset(i8* %dst1, i8* %dst2, i8 %c) {
40 ; CHECK-LABEL: @test_align_memset(
41 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
42 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
43 ; CHECK-NEXT:    ret void
45   call void @llvm.memset.p0i8.i64(i8* align 8 %dst1, i8 %c, i64 128, i1 false)
46   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 128, i1 false)
47   ret void
50 define void @test_different_types(i8* %dst1, i8* %dst2, i8 %c) {
51 ; CHECK-LABEL: @test_different_types(
52 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
53 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* [[DST2:%.*]], i8 [[C]], i32 100, i1 false)
54 ; CHECK-NEXT:    ret void
56   call void @llvm.memset.p0i8.i64(i8* align 8 %dst1, i8 %c, i64 128, i1 false)
57   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst2, i8* %dst1, i32 100, i1 false)
58   ret void
61 define void @test_different_types_2(i8* %dst1, i8* %dst2, i8 %c) {
62 ; CHECK-LABEL: @test_different_types_2(
63 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* align 8 [[DST1:%.*]], i8 [[C:%.*]], i32 128, i1 false)
64 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
65 ; CHECK-NEXT:    ret void
67   call void @llvm.memset.p0i8.i32(i8* align 8 %dst1, i8 %c, i32 128, i1 false)
68   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 100, i1 false)
69   ret void
72 define void @test_different_source_gep(i8* %dst1, i8* %dst2, i8 %c) {
73 ; CHECK-LABEL: @test_different_source_gep(
74 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
75 ; CHECK-NEXT:    [[P:%.*]] = getelementptr i8, i8* [[DST1]], i64 64
76 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST2:%.*]], i8* [[P]], i64 64, i1 false)
77 ; CHECK-NEXT:    ret void
79   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 128, i1 false)
80   ; FIXME: We could optimize this as well.
81   %p = getelementptr i8, i8* %dst1, i64 64
82   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %p, i64 64, i1 false)
83   ret void
86 define void @test_variable_size_1(i8* %dst1, i64 %dst1_size, i8* %dst2, i8 %c) {
87 ; CHECK-LABEL: @test_variable_size_1(
88 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 [[DST1_SIZE:%.*]], i1 false)
89 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST2:%.*]], i8* [[DST1]], i64 128, i1 false)
90 ; CHECK-NEXT:    ret void
92   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 %dst1_size, i1 false)
93   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 128, i1 false)
94   ret void
97 define void @test_variable_size_2(i8* %dst1, i8* %dst2, i64 %dst2_size, i8 %c) {
98 ; CHECK-LABEL: @test_variable_size_2(
99 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
100 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST2:%.*]], i8* [[DST1]], i64 [[DST2_SIZE:%.*]], i1 false)
101 ; CHECK-NEXT:    ret void
103   call void @llvm.memset.p0i8.i64(i8* %dst1, i8 %c, i64 128, i1 false)
104   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %dst1, i64 %dst2_size, i1 false)
105   ret void
108 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
109 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
110 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1)
111 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1)