[Analysis] Be defensive when matching size_t in lib call signatures
authorBjorn Pettersson <bjorn.a.pettersson@ericsson.com>
Mon, 27 Sep 2021 12:12:13 +0000 (14:12 +0200)
committerBjorn Pettersson <bjorn.a.pettersson@ericsson.com>
Tue, 28 Sep 2021 13:29:37 +0000 (15:29 +0200)
When TargetLibraryInfoImpl::isValidProtoForLibFunc is checking
function signatures to detect lib calls it may check that a parameter
or return value matches with the "size_t" type. For this to work it
has to derive the IR type matching with "size_t". Depending on if
a DataLayout is provided or not, this has been done in two different
way. Either a more strict check being based on IntPtrType (which is
given by the DataLayout) or a more relaxed check assuming that any
integer type matches with "size_t".

Given that the stricter approach exist it seems like we do not want
to trigger rewrites etc if we aren't sure that a function calls
actually match with the library function. Therefore it was questioned
why we actually have the more relaxed approach when not being able
to derive an IR type for "size_t". This patch will take a more
defensive approach, requiring that a DataLayout is passed to
isValidProtoForLibFunc.

Differential Revision: https://reviews.llvm.org/D110584

llvm/include/llvm/Analysis/TargetLibraryInfo.h
llvm/lib/Analysis/TargetLibraryInfo.cpp

index c27e109..cc30e13 100644 (file)
@@ -76,7 +76,7 @@ class TargetLibraryInfoImpl {
   /// Return true if the function type FTy is valid for the library function
   /// F, regardless of whether the function is available.
   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
-                              const DataLayout *DL) const;
+                              const DataLayout &DL) const;
 
 public:
   /// List of known vector-functions libraries.
@@ -115,6 +115,8 @@ public:
   ///
   /// If it is one of the known library functions, return true and set F to the
   /// corresponding value.
+  ///
+  /// FDecl is assumed to have a parent Module when using this function.
   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
 
   /// Forces a function to be marked as unavailable.
index bc9aab3..a916ba6 100644 (file)
@@ -725,20 +725,13 @@ bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, LibFunc &F) const {
 
 bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
                                                    LibFunc F,
-                                                   const DataLayout *DL) const {
+                                                   const DataLayout &DL) const {
   LLVMContext &Ctx = FTy.getContext();
   // FIXME: There is really no guarantee that sizeof(size_t) is equal to
   // sizeof(int*) for every target. So the assumption used here to derive the
   // SizeTTy based on DataLayout and getIntPtrType isn't always valid.
-  Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr;
+  Type *SizeTTy = DL.getIntPtrType(Ctx, /*AddressSpace=*/0);
   auto IsSizeTTy = [SizeTTy](Type *Ty) {
-    // FIXME: For uknown historical reasons(?) we use a relaxed condition saying
-    // that any integer type may size_t, for example if we got no
-    // DataLayout. This seems like a potentially error prone relaxation (or why
-    // should we only be more strict and checking the exact type when we have a
-    // DataLayout?).
-    if (!SizeTTy)
-      return Ty->isIntegerTy();
     return Ty == SizeTTy;
   };
   unsigned NumParams = FTy.getNumParams();
@@ -1625,10 +1618,11 @@ bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
   // avoid string normalization and comparison.
   if (FDecl.isIntrinsic()) return false;
 
-  const DataLayout *DL =
-      FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr;
+  const Module *M = FDecl.getParent();
+  assert(M && "Expecting FDecl to be connected to a Module.");
+
   return getLibFunc(FDecl.getName(), F) &&
-         isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL);
+         isValidProtoForLibFunc(*FDecl.getFunctionType(), F, M->getDataLayout());
 }
 
 void TargetLibraryInfoImpl::disableAllFunctions() {