405 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=memcpyopt -S %s -verify-memoryssa | FileCheck %s3 4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"5 6@C = external constant [0 x i8]7 8define void @test_constant(i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) {9; CHECK-LABEL: @test_constant(10; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 011; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])12; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]13; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]14; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]15; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[SRC_SIZE]]16; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)17; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr @C, i64 [[SRC_SIZE]], i1 false)18; CHECK-NEXT: ret void19;20 %non.zero = icmp ne i64 %src_size, 021 call void @llvm.assume(i1 %non.zero)22 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)23 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr @C, i64 %src_size, i1 false)24 ret void25}26 27define void @test(ptr %src, i64 %src_size, ptr noalias %dst, i64 %dst_size, i8 %c) {28; CHECK-LABEL: @test(29; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 030; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])31; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]32; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]33; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]34; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[SRC_SIZE]]35; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)36; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)37; CHECK-NEXT: ret void38;39 %non.zero = icmp ne i64 %src_size, 040 call void @llvm.assume(i1 %non.zero)41 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)42 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)43 ret void44}45 46define void @test_different_types_i32_i64(ptr noalias %dst, ptr %src, i32 %dst_size, i64 %src_size, i8 %c) {47; CHECK-LABEL: @test_different_types_i32_i64(48; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 049; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])50; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[DST_SIZE:%.*]] to i6451; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i64 [[TMP1]], [[SRC_SIZE]]52; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], [[SRC_SIZE]]53; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP3]]54; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[SRC_SIZE]]55; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP5]], i8 [[C:%.*]], i64 [[TMP4]], i1 false)56; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)57; CHECK-NEXT: ret void58;59 %non.zero = icmp ne i64 %src_size, 060 call void @llvm.assume(i1 %non.zero)61 call void @llvm.memset.p0.i32(ptr %dst, i8 %c, i32 %dst_size, i1 false)62 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)63 ret void64}65 66define void @test_different_types_i128_i32(ptr noalias %dst, ptr %src, i128 %dst_size, i32 %src_size, i8 %c) {67; CHECK-LABEL: @test_different_types_i128_i32(68; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i32 [[SRC_SIZE:%.*]], 069; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])70; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SRC_SIZE]] to i12871; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i128 [[DST_SIZE:%.*]], [[TMP1]]72; CHECK-NEXT: [[TMP3:%.*]] = sub i128 [[DST_SIZE]], [[TMP1]]73; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i128 0, i128 [[TMP3]]74; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST:%.*]], i128 [[TMP1]]75; CHECK-NEXT: call void @llvm.memset.p0.i128(ptr align 1 [[TMP5]], i8 [[C:%.*]], i128 [[TMP4]], i1 false)76; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DST]], ptr [[SRC:%.*]], i32 [[SRC_SIZE]], i1 false)77; CHECK-NEXT: ret void78;79 %non.zero = icmp ne i32 %src_size, 080 call void @llvm.assume(i1 %non.zero)81 call void @llvm.memset.p0.i128(ptr %dst, i8 %c, i128 %dst_size, i1 false)82 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %src, i32 %src_size, i1 false)83 ret void84}85 86define void @test_different_types_i32_i128(ptr noalias %dst, ptr %src, i32 %dst_size, i128 %src_size, i8 %c) {87; CHECK-LABEL: @test_different_types_i32_i128(88; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i128 [[SRC_SIZE:%.*]], 089; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])90; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[DST_SIZE:%.*]] to i12891; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i128 [[TMP1]], [[SRC_SIZE]]92; CHECK-NEXT: [[TMP3:%.*]] = sub i128 [[TMP1]], [[SRC_SIZE]]93; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i128 0, i128 [[TMP3]]94; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST:%.*]], i128 [[SRC_SIZE]]95; CHECK-NEXT: call void @llvm.memset.p0.i128(ptr align 1 [[TMP5]], i8 [[C:%.*]], i128 [[TMP4]], i1 false)96; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i128(ptr [[DST]], ptr [[SRC:%.*]], i128 [[SRC_SIZE]], i1 false)97; CHECK-NEXT: ret void98;99 %non.zero = icmp ne i128 %src_size, 0100 call void @llvm.assume(i1 %non.zero)101 call void @llvm.memset.p0.i32(ptr %dst, i8 %c, i32 %dst_size, i1 false)102 call void @llvm.memcpy.p0.p0.i128(ptr %dst, ptr %src, i128 %src_size, i1 false)103 ret void104}105 106define void @test_different_types_i64_i32(ptr noalias %dst, ptr %src, i64 %dst_size, i32 %src_size, i8 %c) {107; CHECK-LABEL: @test_different_types_i64_i32(108; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i32 [[SRC_SIZE:%.*]], 0109; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])110; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SRC_SIZE]] to i64111; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[TMP1]]112; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[DST_SIZE]], [[TMP1]]113; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP3]]114; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[TMP1]]115; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP5]], i8 [[C:%.*]], i64 [[TMP4]], i1 false)116; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DST]], ptr [[SRC:%.*]], i32 [[SRC_SIZE]], i1 false)117; CHECK-NEXT: ret void118;119 %non.zero = icmp ne i32 %src_size, 0120 call void @llvm.assume(i1 %non.zero)121 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)122 call void @llvm.memcpy.p0.p0.i32(ptr %dst, ptr %src, i32 %src_size, i1 false)123 ret void124}125 126define void @test_align_same(ptr %src, ptr noalias %dst, i64 %dst_size) {127; CHECK-LABEL: @test_align_same(128; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], 80129; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], 80130; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]131; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 80132; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 [[TMP3]], i1 false)133; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 80, i1 false)134; CHECK-NEXT: ret void135;136 call void @llvm.memset.p0.i64(ptr align 8 %dst, i8 0, i64 %dst_size, i1 false)137 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 80, i1 false)138 ret void139}140 141define void @test_align_min(ptr %src, ptr noalias %dst, i64 %dst_size) {142; CHECK-LABEL: @test_align_min(143; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], 36144; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], 36145; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]146; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 36147; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP4]], i8 0, i64 [[TMP3]], i1 false)148; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 36, i1 false)149; CHECK-NEXT: ret void150;151 call void @llvm.memset.p0.i64(ptr align 8 %dst, i8 0, i64 %dst_size, i1 false)152 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 36, i1 false)153 ret void154}155 156define void @test_align_memcpy(ptr %src, ptr noalias %dst, i64 %dst_size) {157; CHECK-LABEL: @test_align_memcpy(158; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], 80159; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], 80160; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]161; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 80162; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 [[TMP3]], i1 false)163; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DST]], ptr align 8 [[SRC:%.*]], i64 80, i1 false)164; CHECK-NEXT: ret void165;166 call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 %dst_size, i1 false)167 call void @llvm.memcpy.p0.p0.i64(ptr align 8 %dst, ptr align 8 %src, i64 80, i1 false)168 ret void169}170 171define void @test_non_i8_dst_type(ptr %src, i64 %src_size, ptr noalias %dst_pi64, i64 %dst_size, i8 %c) {172; CHECK-LABEL: @test_non_i8_dst_type(173; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0174; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])175; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]176; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]177; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]178; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST_PI64:%.*]], i64 [[SRC_SIZE]]179; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)180; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST_PI64]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)181; CHECK-NEXT: ret void182;183 %non.zero = icmp ne i64 %src_size, 0184 call void @llvm.assume(i1 %non.zero)185 call void @llvm.memset.p0.i64(ptr %dst_pi64, i8 %c, i64 %dst_size, i1 false)186 call void @llvm.memcpy.p0.p0.i64(ptr %dst_pi64, ptr %src, i64 %src_size, i1 false)187 ret void188}189 190define void @test_different_dst(ptr noalias %dst2, ptr %src, i64 %src_size, ptr noalias %dst, i64 %dst_size) {191; CHECK-LABEL: @test_different_dst(192; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0193; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])194; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST:%.*]], i8 0, i64 [[DST_SIZE:%.*]], i1 false)195; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)196; CHECK-NEXT: ret void197;198 %non.zero = icmp ne i64 %src_size, 0199 call void @llvm.assume(i1 %non.zero)200 call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 %dst_size, i1 false)201 call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %src, i64 %src_size, i1 false)202 ret void203}204 205; Make sure we also take into account dependencies on the destination.206 207define i8 @test_intermediate_read(ptr noalias %a, ptr %b) #0 {208; CHECK-LABEL: @test_intermediate_read(209; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[A:%.*]], i8 0, i64 64, i1 false)210; CHECK-NEXT: [[R:%.*]] = load i8, ptr [[A]], align 1211; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr [[B:%.*]], i64 24, i1 false)212; CHECK-NEXT: ret i8 [[R]]213;214 call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 64, i1 false)215 %r = load i8, ptr %a216 call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 24, i1 false)217 ret i8 %r218}219 220%struct = type { [8 x i8], [8 x i8] }221 222define void @test_intermediate_write(ptr %b) #0 {223; CHECK-LABEL: @test_intermediate_write(224; CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT:%.*]], align 8225; CHECK-NEXT: [[A1:%.*]] = getelementptr [[STRUCT]], ptr [[A]], i32 0, i32 1, i32 0226; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[A]], i8 0, i64 16, i1 false)227; CHECK-NEXT: store i8 1, ptr [[A1]], align 1228; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr [[B:%.*]], i64 8, i1 false)229; CHECK-NEXT: ret void230;231 %a = alloca %struct232 %a1 = getelementptr %struct, ptr %a, i32 0, i32 1, i32 0233 call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 16, i1 false)234 store i8 1, ptr %a1235 call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 8, i1 false)236 ret void237}238 239define void @test_throwing_call(ptr %src, i64 %src_size, ptr noalias %dst, i64 %dst_size, i8 %c) {240; CHECK-LABEL: @test_throwing_call(241; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0242; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])243; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST:%.*]], i8 [[C:%.*]], i64 [[DST_SIZE:%.*]], i1 false)244; CHECK-NEXT: call void @call() #[[ATTR3:[0-9]+]]245; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)246; CHECK-NEXT: ret void247;248 %non.zero = icmp ne i64 %src_size, 0249 call void @llvm.assume(i1 %non.zero)250 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)251 call void @call() readnone252 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)253 ret void254}255 256define void @test_throwing_call_alloca(ptr %src, i64 %src_size, i64 %dst_size, i8 %c) {257; CHECK-LABEL: @test_throwing_call_alloca(258; CHECK-NEXT: [[DST:%.*]] = alloca i8, align 1259; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0260; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])261; CHECK-NEXT: call void @call() #[[ATTR3]]262; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]263; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]264; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]265; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SRC_SIZE]]266; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)267; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)268; CHECK-NEXT: ret void269;270 %dst = alloca i8271 %non.zero = icmp ne i64 %src_size, 0272 call void @llvm.assume(i1 %non.zero)273 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)274 call void @call() readnone275 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)276 ret void277}278 279; %dst and %src in the memcpy may be equal, in which case shorting the memset280; is not legal.281define void @test_missing_noalias(ptr %src, i64 %src_size, ptr %dst, i64 %dst_size, i8 %c) {282; CHECK-LABEL: @test_missing_noalias(283; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0284; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])285; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST:%.*]], i8 [[C:%.*]], i64 [[DST_SIZE:%.*]], i1 false)286; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)287; CHECK-NEXT: ret void288;289 %non.zero = icmp ne i64 %src_size, 0290 call void @llvm.assume(i1 %non.zero)291 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)292 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)293 ret void294}295 296define void @test_same_const_size(ptr noalias %src, ptr noalias %dst, i8 %c) {297; CHECK-LABEL: @test_same_const_size(298; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 16, i1 false)299; CHECK-NEXT: ret void300;301 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 16, i1 false)302 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 16, i1 false)303 ret void304}305 306define void @test_same_dynamic_size(ptr noalias %src, ptr noalias %dst, i64 %size, i8 %c) {307; CHECK-LABEL: @test_same_dynamic_size(308; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SIZE:%.*]], 0309; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])310; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[SIZE]], i1 false)311; CHECK-NEXT: ret void312;313 %non.zero = icmp ne i64 %size, 0314 call void @llvm.assume(i1 %non.zero)315 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %size, i1 false)316 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 false)317 ret void318}319 320; Destinations must alias, but are not trivially equal.321define void @test_must_alias_same_size(ptr noalias %src, ptr noalias %dst, i8 %c) {322; CHECK-LABEL: @test_must_alias_same_size(323; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 16324; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[DST]], i64 16325; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[GEP2]], ptr [[SRC:%.*]], i64 16, i1 false)326; CHECK-NEXT: ret void327;328 %gep1 = getelementptr i8, ptr %dst, i64 16329 call void @llvm.memset.p0.i64(ptr %gep1, i8 %c, i64 16, i1 false)330 %gep2 = getelementptr i8, ptr %dst, i64 16331 call void @llvm.memcpy.p0.p0.i64(ptr %gep2, ptr %src, i64 16, i1 false)332 ret void333}334 335define void @test_must_alias_different_size(ptr noalias %src, i64 %src_size, ptr noalias %dst, i64 %dst_size, i8 %c) {336; CHECK-LABEL: @test_must_alias_different_size(337; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0338; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])339; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 16340; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[DST]], i64 16341; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]342; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]343; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]344; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[SRC_SIZE]]345; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)346; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[GEP2]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)347; CHECK-NEXT: ret void348;349 %non.zero = icmp ne i64 %src_size, 0350 call void @llvm.assume(i1 %non.zero)351 %gep1 = getelementptr i8, ptr %dst, i64 16352 call void @llvm.memset.p0.i64(ptr %gep1, i8 %c, i64 %dst_size, i1 false)353 %gep2 = getelementptr i8, ptr %dst, i64 16354 call void @llvm.memcpy.p0.p0.i64(ptr %gep2, ptr %src, i64 %src_size, i1 false)355 ret void356}357 358define void @test_weird_element_type(ptr %src, i64 %src_size, ptr noalias %dst, i64 %dst_size, i8 %c) {359; CHECK-LABEL: @test_weird_element_type(360; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0361; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])362; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]363; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]364; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]365; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[SRC_SIZE]]366; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)367; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)368; CHECK-NEXT: ret void369;370 %non.zero = icmp ne i64 %src_size, 0371 call void @llvm.assume(i1 %non.zero)372 call void @llvm.memset.p0.i64(ptr %dst, i8 %c, i64 %dst_size, i1 false)373 call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %src_size, i1 false)374 ret void375}376 377define void @test_addrspace(ptr addrspace(1) %src, i64 %src_size, ptr addrspace(1) noalias %dst, i64 %dst_size, i8 %c) {378; CHECK-LABEL: @test_addrspace(379; CHECK-NEXT: [[NON_ZERO:%.*]] = icmp ne i64 [[SRC_SIZE:%.*]], 0380; CHECK-NEXT: call void @llvm.assume(i1 [[NON_ZERO]])381; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE]]382; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]]383; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]384; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(1) [[DST:%.*]], i64 [[SRC_SIZE]]385; CHECK-NEXT: call void @llvm.memset.p1.i64(ptr addrspace(1) align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)386; CHECK-NEXT: call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) [[DST]], ptr addrspace(1) [[SRC:%.*]], i64 [[SRC_SIZE]], i1 false)387; CHECK-NEXT: ret void388;389 %non.zero = icmp ne i64 %src_size, 0390 call void @llvm.assume(i1 %non.zero)391 call void @llvm.memset.p1.i64(ptr addrspace(1) %dst, i8 %c, i64 %dst_size, i1 false)392 call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 %src_size, i1 false)393 ret void394}395 396declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)397declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)398declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1)399declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture readonly, i32, i1)400declare void @llvm.memset.p0.i128(ptr nocapture, i8, i128, i1)401declare void @llvm.memcpy.p0.p0.i128(ptr nocapture, ptr nocapture readonly, i128, i1)402declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture, i8, i64, i1)403declare void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) nocapture, ptr addrspace(1) nocapture readonly, i64, i1)404declare void @call()405