[llvm] Prefer bit_cast, std::array, and llvm::copy over memcpy where intent is clearer (PR #228556)

Younes Yazami via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 15:12:45 PDT 2026


https://github.com/yelidris-public updated https://github.com/llvm/llvm-project/pull/228556

>From ae5f60844e97b7339683d17f8eda2a4ae60d129b Mon Sep 17 00:00:00 2001
From: yelidris <younes.elidrissiyazami at amd.com>
Date: Wed, 30 Sep 2026 12:49:59 -0400
Subject: [PATCH] Prefer std::array and llvm::copy over memcpy where intent is
 clearer

---
 llvm/include/llvm/Analysis/TargetLibraryInfo.h |  3 ++-
 llvm/lib/Analysis/TargetLibraryInfo.cpp        | 16 ++++++----------
 llvm/lib/AsmParser/LLParser.cpp                |  6 ++----
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp  |  2 +-
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h    |  8 ++------
 llvm/lib/Support/APFixedPoint.cpp              | 11 ++++++++---
 llvm/lib/Support/APFloat.cpp                   |  6 ++++--
 llvm/lib/Support/Error.cpp                     |  2 +-
 llvm/lib/Support/MemoryBuffer.cpp              |  2 +-
 llvm/lib/TargetParser/Host.cpp                 |  3 ++-
 llvm/lib/TextAPI/RecordsSlice.cpp              |  2 +-
 11 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 19c251f592608a7..0df6649040b6b80 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -19,6 +19,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/TargetParser/Triple.h"
+#include <array>
 #include <bitset>
 #include <optional>
 
@@ -93,7 +94,7 @@ class VecDesc {
 class TargetLibraryInfoImpl {
   friend class TargetLibraryInfo;
 
-  unsigned char AvailableArray[(NumLibFuncs+3)/4];
+  std::array<unsigned char, (NumLibFuncs + 3) / 4> AvailableArray;
   DenseMap<unsigned, std::string> CustomNames;
 #define GET_TARGET_LIBRARY_INFO_IMPL_DECL
 #include "llvm/Analysis/TargetLibraryInfo.inc"
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index c3469979d720476..6656f43cc6386df 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -910,7 +910,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T,
                                              VectorLibrary VecLib)
     : IsErrnoFunctionCall(initializeIsErrnoFunctionCall(T)) {
   // Default to everything being available.
-  memset(AvailableArray, -1, sizeof(AvailableArray));
+  AvailableArray.fill(0xFF);
 
   initialize(*this, T, StandardNamesStrTable, VecLib);
 }
@@ -921,7 +921,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
       ShouldSignExtI32Return(TLI.ShouldSignExtI32Return),
       SizeOfInt(TLI.SizeOfInt), IsErrnoFunctionCall(TLI.IsErrnoFunctionCall) {
-  memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
+  AvailableArray = TLI.AvailableArray;
   VectorDescs = TLI.VectorDescs;
   ScalarDescs = TLI.ScalarDescs;
 }
@@ -933,8 +933,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
       ShouldSignExtI32Return(TLI.ShouldSignExtI32Return),
       SizeOfInt(TLI.SizeOfInt), IsErrnoFunctionCall(TLI.IsErrnoFunctionCall) {
-  std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
-            AvailableArray);
+  AvailableArray = std::move(TLI.AvailableArray);
   VectorDescs = TLI.VectorDescs;
   ScalarDescs = TLI.ScalarDescs;
 }
@@ -947,7 +946,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoI
   ShouldSignExtI32Return = TLI.ShouldSignExtI32Return;
   SizeOfInt = TLI.SizeOfInt;
   IsErrnoFunctionCall = TLI.IsErrnoFunctionCall;
-  memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
+  AvailableArray = TLI.AvailableArray;
   return *this;
 }
 
@@ -959,8 +958,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&
   ShouldSignExtI32Return = TLI.ShouldSignExtI32Return;
   SizeOfInt = TLI.SizeOfInt;
   IsErrnoFunctionCall = TLI.IsErrnoFunctionCall;
-  std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
-            AvailableArray);
+  AvailableArray = std::move(TLI.AvailableArray);
   return *this;
 }
 
@@ -1229,9 +1227,7 @@ LibFunc TargetLibraryInfoImpl::getLibFunc(unsigned int Opcode, Type *Ty) const {
   return Ty->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf;
 }
 
-void TargetLibraryInfoImpl::disableAllFunctions() {
-  memset(AvailableArray, 0, sizeof(AvailableArray));
-}
+void TargetLibraryInfoImpl::disableAllFunctions() { AvailableArray.fill(0); }
 
 static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) {
   return LHS.getScalarFnName() < RHS.getScalarFnName();
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index cc7633894fb74bc..819227e18af81b0 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -4349,8 +4349,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
 
     ID.ConstantStructElts = std::make_unique<Constant *[]>(Elts.size());
     ID.UIntVal = Elts.size();
-    memcpy(ID.ConstantStructElts.get(), Elts.data(),
-           Elts.size() * sizeof(Elts[0]));
+    llvm::copy(Elts, ID.ConstantStructElts.get());
     ID.Kind = ValID::t_ConstantStruct;
     return false;
   }
@@ -4370,8 +4369,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
 
     if (isPackedStruct) {
       ID.ConstantStructElts = std::make_unique<Constant *[]>(Elts.size());
-      memcpy(ID.ConstantStructElts.get(), Elts.data(),
-             Elts.size() * sizeof(Elts[0]));
+      llvm::copy(Elts, ID.ConstantStructElts.get());
       ID.UIntVal = Elts.size();
       ID.Kind = ValID::t_PackedConstantStruct;
       return false;
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 84ea5e349f01d16..da6d7d925d2575c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -210,7 +210,7 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
     if (F->getChecksum()) {
       std::string Checksum = fromHex(F->getChecksum()->Value);
       void *CKMem = OS.getContext().allocate(Checksum.size(), 1);
-      memcpy(CKMem, Checksum.data(), Checksum.size());
+      llvm::copy(Checksum, static_cast<char *>(CKMem));
       ChecksumAsBytes = ArrayRef<uint8_t>(
           reinterpret_cast<const uint8_t *>(CKMem), Checksum.size());
       switch (F->getChecksum()->Kind) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 9118394f2fe3b51..21da85eb486d88b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -86,12 +86,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
     }
 
     unsigned hashValue() const {
-      uint64_t H = 0;
-      std::memcpy(&H, this, sizeof(uint64_t));
-      static_assert(sizeof(LocalVarDef) == 8 + 4 &&
-                    offsetof(LocalVarDef, DerefOffset) == 8);
-      H = hash_combine(H, DerefOffset);
-      return H;
+      return hash_combine(InMemory, DataOffset, IsSubfield, StructOffset,
+                          CVRegister, DerefOffset);
     }
 
     bool operator==(const LocalVarDef &Other) const {
diff --git a/llvm/lib/Support/APFixedPoint.cpp b/llvm/lib/Support/APFixedPoint.cpp
index ac1607a498be1ad..f8e325afc2358c8 100644
--- a/llvm/lib/Support/APFixedPoint.cpp
+++ b/llvm/lib/Support/APFixedPoint.cpp
@@ -34,9 +34,14 @@ uint32_t FixedPointSemantics::toOpaqueInt() const {
 }
 
 FixedPointSemantics FixedPointSemantics::getFromOpaqueInt(uint32_t I) {
-  FixedPointSemantics F(0, 0, false, false, false);
-  std::memcpy(&F, &I, sizeof(F));
-  return F;
+  unsigned Width = I & maskTrailingOnes<unsigned>(WidthBitWidth);
+  int LsbWeight = SignExtend32<LsbWeightBitWidth>(
+      (I >> WidthBitWidth) & maskTrailingOnes<unsigned>(LsbWeightBitWidth));
+  unsigned Shift = WidthBitWidth + LsbWeightBitWidth;
+  return FixedPointSemantics(Width, Lsb{LsbWeight},
+                             /*IsSigned=*/(I >> Shift) & 1,
+                             /*IsSaturated=*/(I >> (Shift + 1)) & 1,
+                             /*HasUnsignedPadding=*/(I >> (Shift + 2)) & 1);
 }
 
 APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema,
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 3d1932454761f1e..273378664af3ea6 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3325,12 +3325,14 @@ unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits,
 
   switch (category) {
   case fcInfinity:
-    memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
+    llvm::copy(
+        ArrayRef<char>(upperCase ? infinityU : infinityL, sizeof infinityU - 1),
+        dst);
     dst += sizeof infinityL - 1;
     break;
 
   case fcNaN:
-    memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
+    llvm::copy(ArrayRef<char>(upperCase ? NaNU : NaNL, sizeof NaNU - 1), dst);
     dst += sizeof NaNU - 1;
     break;
 
diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp
index c6743155ced8546..199e62bb6e6f8fc 100644
--- a/llvm/lib/Support/Error.cpp
+++ b/llvm/lib/Support/Error.cpp
@@ -191,7 +191,7 @@ void LLVMCantFail(LLVMErrorRef Err) {
 char *LLVMGetErrorMessage(LLVMErrorRef Err) {
   std::string Tmp = toString(unwrap(Err));
   char *ErrMsg = new char[Tmp.size() + 1];
-  memcpy(ErrMsg, Tmp.data(), Tmp.size());
+  llvm::copy(Tmp, ErrMsg);
   ErrMsg[Tmp.size()] = '\0';
   return ErrMsg;
 }
diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp
index 9c49c143cf01c23..99956897fa5367b 100644
--- a/llvm/lib/Support/MemoryBuffer.cpp
+++ b/llvm/lib/Support/MemoryBuffer.cpp
@@ -62,7 +62,7 @@ void MemoryBuffer::init(const char *BufStart, const char *BufEnd,
 /// null-terminates it.
 static void CopyStringRef(char *Memory, StringRef Data) {
   if (!Data.empty())
-    memcpy(Memory, Data.data(), Data.size());
+    llvm::copy(Data, Memory);
   Memory[Data.size()] = 0; // Null terminate string.
 }
 
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index d89133d534b56d3..28cdd5cc0db8589 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1615,7 +1615,8 @@ StringRef sys::getHostCPUName() {
               (PrimaryPartKeyNameSize == SubKeySize &&
                ::memcmp(SubKeyName, PrimaryPartKeyName, SubKeySize) > 0)) {
             PrimaryCpuInfo = RegValue;
-            ::memcpy(PrimaryPartKeyName, SubKeyName, SubKeySize + 1);
+            llvm::copy(ArrayRef<char>(SubKeyName, SubKeySize + 1),
+                       PrimaryPartKeyName);
             PrimaryPartKeyNameSize = SubKeySize;
           }
           if (!llvm::is_contained(Values, RegValue)) {
diff --git a/llvm/lib/TextAPI/RecordsSlice.cpp b/llvm/lib/TextAPI/RecordsSlice.cpp
index 91ad2556e46b81c..8011350c43a1d50 100644
--- a/llvm/lib/TextAPI/RecordsSlice.cpp
+++ b/llvm/lib/TextAPI/RecordsSlice.cpp
@@ -281,7 +281,7 @@ StringRef RecordsSlice::copyString(StringRef String) {
     return String;
 
   void *Ptr = StringAllocator.Allocate(String.size(), 1);
-  memcpy(Ptr, String.data(), String.size());
+  llvm::copy(String, static_cast<char *>(Ptr));
   return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
 }
 



More information about the llvm-commits mailing list