xref: /aosp_15_r20/external/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -memcpyopt -S %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test
6*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
7*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
8*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
9*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
13*9880d681SAndroid Build Coastguard Workerdefine void @test(i8* %src, i64 %src_size, i8* %dst, i64 %dst_size, i8 %c) {
14*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %dst_size, i32 1, i1 false)
15*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
16*9880d681SAndroid Build Coastguard Worker  ret void
17*9880d681SAndroid Build Coastguard Worker}
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_different_types_i32_i64
20*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i64
21*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
22*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 [[DSTSIZE]], %src_size
23*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 [[DSTSIZE]], %src_size
24*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
28*9880d681SAndroid Build Coastguard Workerdefine void @test_different_types_i32_i64(i8* %dst, i8* %src, i32 %dst_size, i64 %src_size, i8 %c) {
29*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i32(i8* %dst, i8 %c, i32 %dst_size, i32 1, i1 false)
30*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
31*9880d681SAndroid Build Coastguard Worker  ret void
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_different_types_i128_i32
35*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i128
36*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 [[SRCSIZE]]
37*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i128 %dst_size, [[SRCSIZE]]
38*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i128 %dst_size, [[SRCSIZE]]
39*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i128(i8* [[DST]], i8 %c, i128 [[SIZE]], i32 1, i1 false)
41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
43*9880d681SAndroid Build Coastguard Workerdefine void @test_different_types_i128_i32(i8* %dst, i8* %src, i128 %dst_size, i32 %src_size, i8 %c) {
44*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i128(i8* %dst, i8 %c, i128 %dst_size, i32 1, i1 false)
45*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
46*9880d681SAndroid Build Coastguard Worker  ret void
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_different_types_i32_i128
50*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i128
51*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 %src_size
52*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i128 [[DSTSIZE]], %src_size
53*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i128 [[DSTSIZE]], %src_size
54*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i128(i8* [[DST]], i8 %c, i128 [[SIZE]], i32 1, i1 false)
56*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i128(i8* %dst, i8* %src, i128 %src_size, i32 1, i1 false)
57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
58*9880d681SAndroid Build Coastguard Workerdefine void @test_different_types_i32_i128(i8* %dst, i8* %src, i32 %dst_size, i128 %src_size, i8 %c) {
59*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i32(i8* %dst, i8 %c, i32 %dst_size, i32 1, i1 false)
60*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i128(i8* %dst, i8* %src, i128 %src_size, i32 1, i1 false)
61*9880d681SAndroid Build Coastguard Worker  ret void
62*9880d681SAndroid Build Coastguard Worker}
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_different_types_i64_i32
65*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i64
66*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 [[SRCSIZE]]
67*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, [[SRCSIZE]]
68*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, [[SRCSIZE]]
69*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
73*9880d681SAndroid Build Coastguard Workerdefine void @test_different_types_i64_i32(i8* %dst, i8* %src, i64 %dst_size, i32 %src_size, i8 %c) {
74*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %dst_size, i32 1, i1 false)
75*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
76*9880d681SAndroid Build Coastguard Worker  ret void
77*9880d681SAndroid Build Coastguard Worker}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_align_same
80*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 {{.*}}, i32 8, i1 false)
81*9880d681SAndroid Build Coastguard Workerdefine void @test_align_same(i8* %src, i8* %dst, i64 %dst_size) {
82*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 %dst_size, i32 8, i1 false)
83*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 80, i32 1, i1 false)
84*9880d681SAndroid Build Coastguard Worker  ret void
85*9880d681SAndroid Build Coastguard Worker}
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_align_min
88*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 {{.*}}, i32 4, i1 false)
89*9880d681SAndroid Build Coastguard Workerdefine void @test_align_min(i8* %src, i8* %dst, i64 %dst_size) {
90*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 %dst_size, i32 8, i1 false)
91*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 36, i32 1, i1 false)
92*9880d681SAndroid Build Coastguard Worker  ret void
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_align_memcpy
96*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 {{.*}}, i32 8, i1 false)
97*9880d681SAndroid Build Coastguard Workerdefine void @test_align_memcpy(i8* %src, i8* %dst, i64 %dst_size) {
98*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 %dst_size, i32 1, i1 false)
99*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 80, i32 8, i1 false)
100*9880d681SAndroid Build Coastguard Worker  ret void
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_non_i8_dst_type
104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %dst = bitcast i64* %dst_pi64 to i8*
105*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
106*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
107*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
108*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
111*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
112*9880d681SAndroid Build Coastguard Workerdefine void @test_non_i8_dst_type(i8* %src, i64 %src_size, i64* %dst_pi64, i64 %dst_size, i8 %c) {
113*9880d681SAndroid Build Coastguard Worker  %dst = bitcast i64* %dst_pi64 to i8*
114*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %dst_size, i32 1, i1 false)
115*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
116*9880d681SAndroid Build Coastguard Worker  ret void
117*9880d681SAndroid Build Coastguard Worker}
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_different_dst
120*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 %dst_size, i32 1, i1 false)
121*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %src, i64 %src_size, i32 1, i1 false)
122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
123*9880d681SAndroid Build Coastguard Workerdefine void @test_different_dst(i8* %dst2, i8* %src, i64 %src_size, i8* %dst, i64 %dst_size) {
124*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 %dst_size, i32 1, i1 false)
125*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst2, i8* %src, i64 %src_size, i32 1, i1 false)
126*9880d681SAndroid Build Coastguard Worker  ret void
127*9880d681SAndroid Build Coastguard Worker}
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; Make sure we also take into account dependencies on the destination.
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @test_intermediate_read
132*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %a, i8 0, i64 64, i32 1, i1 false)
133*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %r = load i8, i8* %a
134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 24, i32 1, i1 false)
135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8 %r
136*9880d681SAndroid Build Coastguard Workerdefine i8 @test_intermediate_read(i8* %a, i8* %b) #0 {
137*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %a, i8 0, i64 64, i32 1, i1 false)
138*9880d681SAndroid Build Coastguard Worker  %r = load i8, i8* %a
139*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 24, i32 1, i1 false)
140*9880d681SAndroid Build Coastguard Worker  ret i8 %r
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker%struct = type { [8 x i8], [8 x i8] }
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test_intermediate_write
146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %a = alloca %struct
147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %a0 = getelementptr %struct, %struct* %a, i32 0, i32 0, i32 0
148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %a1 = getelementptr %struct, %struct* %a, i32 0, i32 1, i32 0
149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %a0, i8 0, i64 16, i32 1, i1 false)
150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i8 1, i8* %a1
151*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a0, i8* %b, i64 8, i32 1, i1 false)
152*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
153*9880d681SAndroid Build Coastguard Workerdefine void @test_intermediate_write(i8* %b) #0 {
154*9880d681SAndroid Build Coastguard Worker  %a = alloca %struct
155*9880d681SAndroid Build Coastguard Worker  %a0 = getelementptr %struct, %struct* %a, i32 0, i32 0, i32 0
156*9880d681SAndroid Build Coastguard Worker  %a1 = getelementptr %struct, %struct* %a, i32 0, i32 1, i32 0
157*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i64(i8* %a0, i8 0, i64 16, i32 1, i1 false)
158*9880d681SAndroid Build Coastguard Worker  store i8 1, i8* %a1
159*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a0, i8* %b, i64 8, i32 1, i1 false)
160*9880d681SAndroid Build Coastguard Worker  ret void
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
164*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
165*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1)
166*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
167*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i128(i8* nocapture, i8, i128, i32, i1)
168*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i128(i8* nocapture, i8* nocapture readonly, i128, i32, i1)
169