[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