https://github.com/addmisol updated https://github.com/llvm/llvm-project/pull/198558
>From e0052fd57a0225829c5058063fe80e3fb84b2959 Mon Sep 17 00:00:00 2001 From: addmisol <[email protected]> Date: Wed, 2 Sep 2026 18:02:12 +0530 Subject: [PATCH] [MemCpyOpt] Remove libcall availability checks for memory intrinsics Signed-off-by: addmisol <[email protected]> --- clang/lib/Driver/ToolChains/Cuda.cpp | 4 +- .../lib/Transforms/Scalar/MemCpyOptimizer.cpp | 19 +------- llvm/test/Transforms/MemCpyOpt/no-libcalls.ll | 46 +++++++------------ 3 files changed, 18 insertions(+), 51 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 7ad712adf3eb4..94d2c4e839236 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -917,9 +917,7 @@ void CudaToolChain::addClangTargetOptions( DeviceOffloadingKind == Action::OFK_Cuda || UsesLLVMOffloading) && "Only OpenMP or CUDA offloading kinds are supported for NVIDIA GPUs."); - CC1Args.append({"-fcuda-is-device", "-mllvm", - "-enable-memcpyopt-without-libcalls", - "-fno-threadsafe-statics"}); + CC1Args.append({"-fcuda-is-device", "-fno-threadsafe-statics"}); if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false)) diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 538e50d6fc74e..6f8c573a6dc69 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -64,10 +64,6 @@ using namespace llvm; #define DEBUG_TYPE "memcpyopt" -static cl::opt<bool> EnableMemCpyOptWithoutLibcalls( - "enable-memcpyopt-without-libcalls", cl::Hidden, - cl::desc("Enable memcpyopt even when libcalls are disabled")); - STATISTIC(NumMemCpyInstr, "Number of memcpy instructions deleted"); STATISTIC(NumMemMoveInstr, "Number of memmove instructions deleted"); STATISTIC(NumMemSetInfer, "Number of memsets inferred"); @@ -636,13 +632,7 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI, BatchAAResults BAA(*AA, EEA); auto *T = LI->getType(); - // Don't introduce calls to memcpy/memmove intrinsics out of thin air if - // the corresponding libcalls are not available. - // TODO: We should really distinguish between libcall availability and - // our ability to introduce intrinsics. - if (T->isAggregateType() && - (EnableMemCpyOptWithoutLibcalls || - (TLI->has(LibFunc_memcpy) && TLI->has(LibFunc_memmove)))) { + if (T->isAggregateType()) { MemoryLocation LoadLoc = MemoryLocation::get(LI); // We use alias analysis to check if an instruction may store to @@ -768,13 +758,6 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) { if (auto *LI = dyn_cast<LoadInst>(StoredVal)) return processStoreOfLoad(SI, LI, DL, BBI); - // The following code creates memset intrinsics out of thin air. Don't do - // this if the corresponding libfunc is not available. - // TODO: We should really distinguish between libcall availability and - // our ability to introduce intrinsics. - if (!(TLI->has(LibFunc_memset) || EnableMemCpyOptWithoutLibcalls)) - return false; - // There are two cases that are interesting for this code to handle: memcpy // and memset. Right now we only handle memset. diff --git a/llvm/test/Transforms/MemCpyOpt/no-libcalls.ll b/llvm/test/Transforms/MemCpyOpt/no-libcalls.ll index f6b6fcd2d0ac7..bed32537e475d 100644 --- a/llvm/test/Transforms/MemCpyOpt/no-libcalls.ll +++ b/llvm/test/Transforms/MemCpyOpt/no-libcalls.ll @@ -1,29 +1,20 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -passes=memcpyopt -mtriple=x86_64 < %s | FileCheck %s --check-prefixes=CHECK,LIBCALLS -; RUN: opt -S -passes=memcpyopt -mtriple=amdgpu-- < %s | FileCheck %s --check-prefixes=CHECK,NO-LIBCALLS -; RUN: opt -S -passes=memcpyopt -mtriple=amdgpu-- -enable-memcpyopt-without-libcalls < %s \ -; RUN: | FileCheck %s --check-prefixes=CHECK,LIBCALLS +; RUN: opt -S -passes=memcpyopt -mtriple=x86_64 < %s | FileCheck %s +; RUN: opt -S -passes=memcpyopt -mtriple=amdgcn-- < %s | FileCheck %s + +; Optimization should happen regardless of libcall availability, as +; PreISelIntrinsicLowering can expand memory intrinsics into loops. ; REQUIRES: amdgpu-registered-target ; REQUIRES: x86-registered-target -define void @dont_create_memset(ptr %p) { -; LIBCALLS-LABEL: @dont_create_memset( -; LIBCALLS-NEXT: [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1 -; LIBCALLS-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i64 2 -; LIBCALLS-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P]], i64 3 -; LIBCALLS-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P]], i8 0, i64 16, i1 false) -; LIBCALLS-NEXT: ret void -; -; NO-LIBCALLS-LABEL: @dont_create_memset( -; NO-LIBCALLS-NEXT: store i32 0, ptr [[P:%.*]], align 4 -; NO-LIBCALLS-NEXT: [[P1:%.*]] = getelementptr i32, ptr [[P]], i64 1 -; NO-LIBCALLS-NEXT: store i32 0, ptr [[P1]], align 4 -; NO-LIBCALLS-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i64 2 -; NO-LIBCALLS-NEXT: store i32 0, ptr [[P2]], align 4 -; NO-LIBCALLS-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P]], i64 3 -; NO-LIBCALLS-NEXT: store i32 0, ptr [[P3]], align 4 -; NO-LIBCALLS-NEXT: ret void +define void @stores_to_memset(ptr %p) { +; CHECK-LABEL: @stores_to_memset( +; CHECK-NEXT: [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1 +; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i64 2 +; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P]], i64 3 +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P]], i8 0, i64 16, i1 false) +; CHECK-NEXT: ret void ; store i32 0, ptr %p %p1 = getelementptr i32, ptr %p, i64 1 @@ -37,15 +28,10 @@ define void @dont_create_memset(ptr %p) { %ty = type { i64 } -define void @dont_create_memcpy(ptr %p1, ptr %p2) { -; LIBCALLS-LABEL: @dont_create_memcpy( -; LIBCALLS-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 8 [[P2:%.*]], ptr align 8 [[P1:%.*]], i64 8, i1 false) -; LIBCALLS-NEXT: ret void -; -; NO-LIBCALLS-LABEL: @dont_create_memcpy( -; NO-LIBCALLS-NEXT: [[V:%.*]] = load [[TY:%.*]], ptr [[P1:%.*]], align 8 -; NO-LIBCALLS-NEXT: store [[TY]] [[V]], ptr [[P2:%.*]], align 8 -; NO-LIBCALLS-NEXT: ret void +define void @load_store_to_memmove(ptr %p1, ptr %p2) { +; CHECK-LABEL: @load_store_to_memmove( +; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 8 [[P2:%.*]], ptr align 8 [[P1:%.*]], i64 8, i1 false) +; CHECK-NEXT: ret void ; %v = load %ty, ptr %p1 store %ty %v, ptr %p2 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
