[clang] [llvm] [Clang] Fix argument extensions in CGBlocks.cpp (PR #111740)

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 11 03:18:54 PDT 2024


https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/111740

>From fb8b76aca00b97166e56fcaefc241850b2535f94 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Wed, 9 Oct 2024 18:51:22 +0200
Subject: [PATCH 1/3] Add SExt attr to 2nd arg

---
 clang/lib/CodeGen/CGBlocks.cpp      | 3 +++
 llvm/include/llvm/IR/DerivedTypes.h | 3 +++
 llvm/lib/IR/Type.cpp                | 8 ++++++++
 3 files changed, 14 insertions(+)

diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 684fda74407313..0f71163b565d6e 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -2842,6 +2842,8 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
   BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
+  // FIXME: Correct signedness of extension??
+  BlockObjectDispose.getAsFunction()->addParamAttr(1, llvm::Attribute::SExt);
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
   return BlockObjectDispose;
@@ -2855,6 +2857,7 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
   BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");
+  BlockObjectAssign.getAsFunction()->addParamAttr(2, llvm::Attribute::SExt);
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
   return BlockObjectAssign;
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index a24801d8bdf834..efacca6d773abf 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -29,6 +29,7 @@
 
 namespace llvm {
 
+class Function;
 class Value;
 class APInt;
 class LLVMContext;
@@ -189,6 +190,8 @@ class FunctionCallee {
 
   explicit operator bool() { return Callee; }
 
+  Function *getAsFunction();
+
 private:
   FunctionType *FnTy = nullptr;
   Value *Callee = nullptr;
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index f618263f79c313..2252e4fb39fc6a 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -361,6 +361,14 @@ bool FunctionType::isValidArgumentType(Type *ArgTy) {
   return ArgTy->isFirstClassType();
 }
 
+//===----------------------------------------------------------------------===//
+//                       FunctionCallee Implementation
+//===----------------------------------------------------------------------===//
+
+Function* FunctionCallee::getAsFunction() {
+  return cast<llvm::Function>(Callee);
+}
+
 //===----------------------------------------------------------------------===//
 //                       StructType Implementation
 //===----------------------------------------------------------------------===//

>From 66b9b8a42dfa478ec51ab721382ed64ffaf0462e Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Thu, 10 Oct 2024 16:35:15 +0200
Subject: [PATCH 2/3] Try overlaoding CreateRuntimeFunction() instead

---
 clang/lib/CodeGen/CGBlocks.cpp      |  8 ++++----
 clang/lib/CodeGen/CGBuiltin.cpp     |  2 +-
 clang/lib/CodeGen/CodeGenModule.cpp | 30 +++++++++++++++++++++++++++++
 clang/lib/CodeGen/CodeGenModule.h   | 10 ++++++++++
 llvm/include/llvm/IR/DerivedTypes.h |  3 ---
 llvm/lib/IR/Type.cpp                |  8 --------
 6 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 0f71163b565d6e..e338bd8e77a9ba 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -2841,9 +2841,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
   llvm::Type *args[] = { Int8PtrTy, Int32Ty };
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
-  BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
+  BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose",
+                           {{AttrIndex::FirstArgIndex + 1, AttrKind::SExt}});
   // FIXME: Correct signedness of extension??
-  BlockObjectDispose.getAsFunction()->addParamAttr(1, llvm::Attribute::SExt);
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
   return BlockObjectDispose;
@@ -2856,8 +2856,8 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
   llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
-  BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");
-  BlockObjectAssign.getAsFunction()->addParamAttr(2, llvm::Attribute::SExt);
+  BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign",
+                           {{AttrIndex::FirstArgIndex + 2, AttrKind::SExt}});
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
   return BlockObjectAssign;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 57705f2d2d0423..f7355c2f5dc64a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18869,7 +18869,7 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
     return EmitRuntimeCall(CGM.CreateRuntimeFunction(
         llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index",
-        {}, false, true));
+        llvm::AttributeList(), false, true));
   }
   case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
     Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 25c1c496a4f27f..4feccbc019786f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4755,6 +4755,15 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
     llvm::AttrBuilder B(F->getContext(), ExtraAttrs.getFnAttrs());
     F->addFnAttrs(B);
   }
+  if (ExtraAttrs.hasRetAttrs()) {
+    llvm::AttrBuilder B(F->getContext(), ExtraAttrs.getRetAttrs());
+    F->addRetAttrs(B);
+  }
+  for (unsigned i = 0; i < F->arg_size(); ++i)
+    if (ExtraAttrs.hasParamAttrs(i)) {
+      llvm::AttrBuilder B(F->getContext(), ExtraAttrs.getParamAttrs(i));
+      F->addParamAttrs(i, B);
+    }
 
   if (!DontDefer) {
     // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
@@ -4938,6 +4947,27 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
   return {FTy, C};
 }
 
+llvm::FunctionCallee
+CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
+                                     ArrayRef<ArgExtAttr> ArgAttrs,
+                                     bool Local, bool AssumeConvergent) {
+  const auto &T = getTarget().getTriple();
+  llvm::AttributeList AL;
+  for (auto &A : ArgAttrs) {
+    bool Signed = (A.second == AttrKind::SExt);
+    AttrKind AK;
+    if (A.first == AttrIndex::ReturnIndex)
+      AK = llvm::TargetLibraryInfo::getExtAttrForI32Return(T, Signed);
+    else if (A.first >= AttrIndex::FirstArgIndex)
+      AK = llvm::TargetLibraryInfo::getExtAttrForI32Param(T, Signed);
+    else
+      llvm_unreachable("Only expecting return or argument indices.");
+    AL = AL.addAttributeAtIndex(getLLVMContext(), A.first, AK);
+  }
+
+  return CreateRuntimeFunction(Ty, Name, AL, Local, AssumeConvergent);
+}
+
 /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
 /// create and return an llvm GlobalVariable with the specified type and address
 /// space. If there is something in the module with the specified name, return
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index c58bb88035ca8a..d63256ee83983d 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1252,6 +1252,16 @@ class CodeGenModule : public CodeGenTypeCache {
                         llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
                         bool Local = false, bool AssumeConvergent = false);
 
+  /// Same as above except that argument extension attributes are passed in
+  /// which are added in a target-dependent way before proceeding.
+  using AttrIndex = llvm::AttributeList::AttrIndex;
+  using AttrKind = llvm::Attribute::AttrKind;
+  typedef std::pair<unsigned, AttrKind> ArgExtAttr;
+  llvm::FunctionCallee
+  CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
+                        ArrayRef<ArgExtAttr> ArgAttrs,
+                        bool Local = false, bool AssumeConvergent = false);
+
   /// Create a new runtime global variable with the specified type and name.
   llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
                                         StringRef Name);
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index efacca6d773abf..a24801d8bdf834 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -29,7 +29,6 @@
 
 namespace llvm {
 
-class Function;
 class Value;
 class APInt;
 class LLVMContext;
@@ -190,8 +189,6 @@ class FunctionCallee {
 
   explicit operator bool() { return Callee; }
 
-  Function *getAsFunction();
-
 private:
   FunctionType *FnTy = nullptr;
   Value *Callee = nullptr;
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 2252e4fb39fc6a..f618263f79c313 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -361,14 +361,6 @@ bool FunctionType::isValidArgumentType(Type *ArgTy) {
   return ArgTy->isFirstClassType();
 }
 
-//===----------------------------------------------------------------------===//
-//                       FunctionCallee Implementation
-//===----------------------------------------------------------------------===//
-
-Function* FunctionCallee::getAsFunction() {
-  return cast<llvm::Function>(Callee);
-}
-
 //===----------------------------------------------------------------------===//
 //                       StructType Implementation
 //===----------------------------------------------------------------------===//

>From f2917c911ae93cefbeaada633e1ccb3cf96fdd8e Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 11 Oct 2024 11:43:58 +0200
Subject: [PATCH 3/3] getExtAttrs() instead.

---
 clang/lib/CodeGen/CGBlocks.cpp      | 10 ++++---
 clang/lib/CodeGen/CGBuiltin.cpp     |  2 +-
 clang/lib/CodeGen/CodeGenModule.cpp | 45 +++++++++++++++++++----------
 clang/lib/CodeGen/CodeGenModule.h   | 12 +++-----
 4 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index e338bd8e77a9ba..35ce3cf1bc81aa 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -2841,8 +2841,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
   llvm::Type *args[] = { Int8PtrTy, Int32Ty };
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
-  BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose",
-                           {{AttrIndex::FirstArgIndex + 1, AttrKind::SExt}});
+  llvm::AttributeList AL =
+      getTargetExtAttrs({AttrKind::None, AttrKind::None, AttrKind::SExt});
+  BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose", AL);
   // FIXME: Correct signedness of extension??
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
@@ -2856,8 +2857,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
   llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
   llvm::FunctionType *fty
     = llvm::FunctionType::get(VoidTy, args, false);
-  BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign",
-                           {{AttrIndex::FirstArgIndex + 2, AttrKind::SExt}});
+  llvm::AttributeList AL = getTargetExtAttrs(
+      {AttrKind::None, AttrKind::None, AttrKind::None, AttrKind::SExt});
+  BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign", AL);
   configureBlocksRuntimeObject(
       *this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
   return BlockObjectAssign;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f7355c2f5dc64a..57705f2d2d0423 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18869,7 +18869,7 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
   case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
     return EmitRuntimeCall(CGM.CreateRuntimeFunction(
         llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index",
-        llvm::AttributeList(), false, true));
+        {}, false, true));
   }
   case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
     Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4feccbc019786f..a7e4ce3ba4f7db 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4947,25 +4947,38 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
   return {FTy, C};
 }
 
-llvm::FunctionCallee
-CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
-                                     ArrayRef<ArgExtAttr> ArgAttrs,
-                                     bool Local, bool AssumeConvergent) {
+llvm::AttributeList
+CodeGenModule::getTargetExtAttrs(ArrayRef<AttrKind> Extensions) {
+  using AttrIndex = llvm::AttributeList::AttrIndex;
+  assert(Extensions.size() && "Empty array not expected.");
   const auto &T = getTarget().getTriple();
   llvm::AttributeList AL;
-  for (auto &A : ArgAttrs) {
-    bool Signed = (A.second == AttrKind::SExt);
-    AttrKind AK;
-    if (A.first == AttrIndex::ReturnIndex)
-      AK = llvm::TargetLibraryInfo::getExtAttrForI32Return(T, Signed);
-    else if (A.first >= AttrIndex::FirstArgIndex)
-      AK = llvm::TargetLibraryInfo::getExtAttrForI32Param(T, Signed);
-    else
-      llvm_unreachable("Only expecting return or argument indices.");
-    AL = AL.addAttributeAtIndex(getLLVMContext(), A.first, AK);
-  }
 
-  return CreateRuntimeFunction(Ty, Name, AL, Local, AssumeConvergent);
+  bool IsSigned;
+  auto isExtension = [&IsSigned](AttrKind AK) -> bool {
+    assert((AK == AttrKind::None || AK == AttrKind::SExt ||
+            AK == AttrKind::ZExt) &&
+           "Unhandled extension attribute.");
+    if (AK != AttrKind::SExt && AK != AttrKind::ZExt)
+      return false;
+    IsSigned = (AK == AttrKind::SExt);
+    return true;
+  };
+
+  if (isExtension(Extensions[0])) { // Returned value at index 0.
+    AttrKind AK = llvm::TargetLibraryInfo::getExtAttrForI32Return(T, IsSigned);
+    if (AK != AttrKind::None)
+      AL = AL.addAttributeAtIndex(getLLVMContext(), AttrIndex::ReturnIndex, AK);
+  }
+  for (unsigned i = 1; i < Extensions.size(); ++i)
+    if (isExtension(Extensions[i])) {
+      AttrKind AK = llvm::TargetLibraryInfo::getExtAttrForI32Param(T, IsSigned);
+      if (AK != AttrKind::None)
+        AL = AL.addAttributeAtIndex(getLLVMContext(),
+                                    AttrIndex::FirstArgIndex + i - 1, AK);
+    }
+
+  return AL;
 }
 
 /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index d63256ee83983d..4f0f0c4546e1ac 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1252,15 +1252,11 @@ class CodeGenModule : public CodeGenTypeCache {
                         llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
                         bool Local = false, bool AssumeConvergent = false);
 
-  /// Same as above except that argument extension attributes are passed in
-  /// which are added in a target-dependent way before proceeding.
-  using AttrIndex = llvm::AttributeList::AttrIndex;
+  /// Return the extension attributes as an AttributeList after any needed
+  /// adjustments for target. The \Param Extensions list begins with the
+  /// return value and then continues with the arguments.
   using AttrKind = llvm::Attribute::AttrKind;
-  typedef std::pair<unsigned, AttrKind> ArgExtAttr;
-  llvm::FunctionCallee
-  CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
-                        ArrayRef<ArgExtAttr> ArgAttrs,
-                        bool Local = false, bool AssumeConvergent = false);
+  llvm::AttributeList getTargetExtAttrs(ArrayRef<AttrKind> Extensions);
 
   /// Create a new runtime global variable with the specified type and name.
   llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,



More information about the llvm-commits mailing list