llvm-project/llvm/test/Transforms/MemCpyOpt/memset-memcpy-to-2x-memset.ll
Jameson Nash 7460c700ae
[MemCpyOpt] handle memcpy from memset in more cases (#140954)
This aims to reduce the divergence between the initial checks in this
function and processMemCpyMemCpyDependence (in particular, adding
handling of offsets), with the goal to eventually reduce duplication
there and improve this pass in other ways.
2025-06-11 10:42:05 +02:00

111 lines
5.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=memcpyopt -S %s -verify-memoryssa | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
define void @test(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %dst2, ptr align 8 %dst1, i64 128, i1 false)
ret void
}
define void @test_smaller_memcpy(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_smaller_memcpy(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 100, i1 false)
ret void
}
define void @test_smaller_memset(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_smaller_memset(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 100, i1 false)
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 128, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 100, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
ret void
}
define void @test_align_memset(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_align_memset(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 128, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr align 8 %dst1, i8 %c, i64 128, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
ret void
}
define void @test_different_types(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_types(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr [[DST2:%.*]], i8 [[C]], i32 100, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr align 8 %dst1, i8 %c, i64 128, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr %dst2, ptr %dst1, i32 100, i1 false)
ret void
}
define void @test_different_types_2(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_types_2(
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 8 [[DST1:%.*]], i8 [[C:%.*]], i32 128, i1 false)
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 100, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i32(ptr align 8 %dst1, i8 %c, i32 128, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 100, i1 false)
ret void
}
define void @test_different_source_gep(ptr %dst1, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_different_source_gep(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[DST1]], i64 64
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST2:%.*]], i8 [[C]], i64 64, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
%p = getelementptr i8, ptr %dst1, i64 64
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %p, i64 64, i1 false)
ret void
}
define void @test_variable_size_1(ptr %dst1, i64 %dst1_size, ptr %dst2, i8 %c) {
; CHECK-LABEL: @test_variable_size_1(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 [[DST1_SIZE:%.*]], i1 false)
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 128, i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 %dst1_size, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 128, i1 false)
ret void
}
define void @test_variable_size_2(ptr %dst1, ptr %dst2, i64 %dst2_size, i8 %c) {
; CHECK-LABEL: @test_variable_size_2(
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[DST1:%.*]], i8 [[C:%.*]], i64 128, i1 false)
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST2:%.*]], ptr [[DST1]], i64 [[DST2_SIZE:%.*]], i1 false)
; CHECK-NEXT: ret void
;
call void @llvm.memset.p0.i64(ptr %dst1, i8 %c, i64 128, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %dst1, i64 %dst2_size, i1 false)
ret void
}
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1)
declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture readonly, i32, i1)