[clang] [CIR] Upstream support for function/call calling conventions (PR #181170)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 12 07:58:09 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Akimasa Watanuki (Men-cotton)
<details>
<summary>Changes</summary>
related: https://github.com/llvm/llvm-project/issues/175871, https://github.com/llvm/llvm-project/issues/179278
Add CIR calling convention enum values and propagate `calling_conv` through `cir.func` and `cir.call`.
Propagate AST calling conventions in CIR codegen (including device kernel mapping).
Lower supported calling conventions to LLVM for both functions and calls.
Add IR/CodeGen/Lowering tests for both supported and unsupported cases.
---
Patch is 36.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/181170.diff
22 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.td (+1)
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+17-3)
- (modified) clang/include/clang/CIR/Interfaces/CIROpInterfaces.td (+3)
- (modified) clang/include/clang/CIR/MissingFeatures.h (+2-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+11-16)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+30-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp (-9)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+1-6)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+22-3)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+3)
- (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+4)
- (modified) clang/lib/CIR/CodeGen/TargetInfo.h (+5)
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+58-11)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+35-9)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (-2)
- (added) clang/test/CIR/CodeGen/call-conv-device-kernel.c (+15)
- (added) clang/test/CIR/CodeGen/call-conv-unsupported.c (+5)
- (added) clang/test/CIR/IR/call-op-call-conv.cir (+19)
- (added) clang/test/CIR/IR/func-call-conv.cir (+23)
- (added) clang/test/CIR/Lowering/call-conv-opencl-kernel.cir (+9)
- (added) clang/test/CIR/Lowering/call-op-call-conv.cir (+19)
- (added) clang/test/CIR/Lowering/func-call-conv.cir (+18)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 3e134d952b8b5..5d2281be01baf 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -41,6 +41,7 @@ def CIR_Dialect : Dialect {
static llvm::StringRef getNoThrowAttrName() { return "nothrow"; }
static llvm::StringRef getNoReturnAttrName() { return "noreturn"; }
static llvm::StringRef getSideEffectAttrName() { return "side_effect"; }
+ static llvm::StringRef getCallingConvAttrName() { return "calling_conv"; }
static llvm::StringRef getReturnsTwiceAttrName() { return "returns_twice"; }
static llvm::StringRef getColdAttrName() { return "cold"; }
static llvm::StringRef getHotAttrName() { return "hot"; }
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4fdffec37c401..eb0552954d3ae 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3091,9 +3091,16 @@ def CIR_OptionalPriorityAttr : OptionalAttr<
>
>;
-// TODO(CIR): CallingConv is a placeholder here so we can use it in
-// infrastructure calls, but it currently has no values.
-def CIR_CallingConv : CIR_I32EnumAttr<"CallingConv", "calling convention", []>;
+// The enumeration values are not necessarily in sync with `clang::CallingConv`
+// or `llvm::CallingConv`.
+def CIR_CallingConv : CIR_I32EnumAttr<"CallingConv", "calling convention", [
+ I32EnumAttrCase<"C", 1, "c">,
+ I32EnumAttrCase<"SpirKernel", 2, "spir_kernel">,
+ I32EnumAttrCase<"SpirFunction", 3, "spir_function">,
+ I32EnumAttrCase<"OpenCLKernel", 4, "opencl_kernel">,
+ I32EnumAttrCase<"PTXKernel", 5, "ptx_kernel">,
+ I32EnumAttrCase<"AMDGPUKernel", 6, "amdgpu_kernel">
+]>;
def CIR_FuncOp : CIR_Op<"func", [
AutomaticAllocationScope, CallableOpInterface, FunctionOpInterface,
@@ -3109,6 +3116,9 @@ def CIR_FuncOp : CIR_Op<"func", [
The function linkage information is specified by `linkage`, as defined by
`GlobalLinkageKind` attribute.
+ The `calling_conv` attribute specifies the calling convention of the
+ function. The default calling convention is `CallingConv::C`.
+
A compiler builtin function must be marked as `builtin` for further
processing when lowering from CIR.
@@ -3178,6 +3188,9 @@ def CIR_FuncOp : CIR_Op<"func", [
CIR_GlobalLinkageKind,
"cir::GlobalLinkageKind::ExternalLinkage"
>:$linkage,
+ DefaultValuedAttr<
+ CIR_CallingConv, "CallingConv::C"
+ >:$calling_conv,
OptionalAttr<StrAttr>:$sym_visibility,
UnitAttr:$comdat,
OptionalAttr<DictArrayAttr>:$arg_attrs,
@@ -3364,6 +3377,7 @@ class CIR_CallOpBase<string mnemonic, list<Trait> extra_traits = []>
dag commonArgs = (ins OptionalAttr<FlatSymbolRefAttr>:$callee,
Variadic<CIR_AnyType>:$args,
+ DefaultValuedAttr<CIR_CallingConv, "CallingConv::C">:$calling_conv,
UnitAttr:$nothrow,
DefaultValuedAttr<CIR_SideEffect, "SideEffect::All">:$side_effect);
}
diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index 4702b4ef08acc..e2255da20866f 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -34,6 +34,9 @@ let cppNamespace = "::cir" in {
"Return the number of operands, accounts for indirect call or "
"exception info",
"unsigned", "getNumArgOperands", (ins)>,
+ InterfaceMethod<
+ "Return the calling convention of the call operation",
+ "cir::CallingConv", "getCallingConv", (ins)>,
InterfaceMethod<"Return whether the callee is nothrow",
"bool", "getNothrow", (ins)>,
InterfaceMethod<"Return the side effects of the call operation",
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 5cb0991326a3c..918a54cd4d571 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -71,7 +71,7 @@ struct MissingFeatures {
static bool opFuncArmNewAttr() { return false; }
static bool opFuncArmStreamingAttr() { return false; }
static bool opFuncAstDeclAttr() { return false; }
- static bool opFuncCallingConv() { return false; }
+ static bool opFuncCallingConv() { return true; }
static bool opFuncColdHotAttr() { return false; }
static bool opFuncCPUAndFeaturesAttributes() { return false; }
static bool opFuncExceptions() { return false; }
@@ -103,7 +103,7 @@ struct MissingFeatures {
static bool opCallImplicitObjectSizeArgs() { return false; }
static bool opCallReturn() { return false; }
static bool opCallArgEvaluationOrder() { return false; }
- static bool opCallCallConv() { return false; }
+ static bool opCallCallConv() { return true; }
static bool opCallSideEffect() { return false; }
static bool opCallMustTail() { return false; }
static bool opCallInAlloca() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index cfbba27e12b93..270c2978f52cb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -20,10 +20,9 @@
using namespace clang;
using namespace clang::CIRGen;
-CIRGenFunctionInfo *
-CIRGenFunctionInfo::create(FunctionType::ExtInfo info, CanQualType resultType,
- llvm::ArrayRef<CanQualType> argTypes,
- RequiredArgs required) {
+CIRGenFunctionInfo *CIRGenFunctionInfo::create(
+ cir::CallingConv cirCC, FunctionType::ExtInfo info, CanQualType resultType,
+ llvm::ArrayRef<CanQualType> argTypes, RequiredArgs required) {
// The first slot allocated for arg type slot is for the return value.
void *buffer = operator new(
totalSizeToAlloc<CanQualType>(argTypes.size() + 1));
@@ -32,6 +31,9 @@ CIRGenFunctionInfo::create(FunctionType::ExtInfo info, CanQualType resultType,
CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo();
+ fi->callingConvention = cirCC;
+ fi->effectiveCallingConvention = cirCC;
+ fi->astCallingConvention = info.getCC();
fi->noReturn = info.getNoReturn();
fi->required = required;
@@ -316,7 +318,7 @@ void CIRGenModule::constructAttributeList(llvm::StringRef name,
cir::CallingConv &callingConv,
cir::SideEffect &sideEffect,
bool attrOnCallSite, bool isThunk) {
- assert(!cir::MissingFeatures::opCallCallConv());
+ callingConv = info.getEffectiveCallingConvention();
sideEffect = cir::SideEffect::All;
auto addUnitAttr = [&](llvm::StringRef name) {
@@ -799,7 +801,7 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
cir::FuncOp directFuncOp,
const SmallVectorImpl<mlir::Value> &cirCallArgs, bool isInvoke,
- const mlir::NamedAttrList &attrs) {
+ cir::CallingConv callingConv, const mlir::NamedAttrList &attrs) {
CIRGenBuilderTy &builder = cgf.getBuilder();
assert(!cir::MissingFeatures::opCallSurroundingTry());
@@ -835,6 +837,7 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
callOpWithExceptions =
builder.createCallOp(callLoc, directFuncOp, cirCallArgs);
+ callOpWithExceptions.setCallingConv(callingConv);
cgf.populateCatchHandlersIfRequired(tryOp);
return callOpWithExceptions;
@@ -844,13 +847,12 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::CallOp op;
if (indirectFuncTy) {
- // TODO(cir): Set calling convention for indirect calls.
- assert(!cir::MissingFeatures::opCallCallConv());
op = builder.createIndirectCallOp(callLoc, indirectFuncVal, indirectFuncTy,
cirCallArgs, attrs);
} else {
op = builder.createCallOp(callLoc, directFuncOp, cirCallArgs, attrs);
}
+ op.setCallingConv(callingConv);
return op;
}
@@ -966,7 +968,6 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
if (auto calleeFuncOp = dyn_cast<cir::FuncOp>(calleePtr))
funcName = calleeFuncOp.getName();
- assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallAttrs());
cir::CallingConv callingConv;
cir::SideEffect sideEffect;
@@ -1009,7 +1010,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
mlir::Location callLoc = loc;
cir::CIRCallOpInterface theCall =
emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
- cirCallArgs, isInvoke, attrs);
+ cirCallArgs, isInvoke, callingConv, attrs);
if (callOp)
*callOp = theCall;
@@ -1074,9 +1075,6 @@ void CallArg::copyInto(CIRGenFunction &cgf, Address addr,
mlir::Value CIRGenFunction::emitRuntimeCall(mlir::Location loc,
cir::FuncOp callee,
ArrayRef<mlir::Value> args) {
- // TODO(cir): set the calling convention to this runtime call.
- assert(!cir::MissingFeatures::opFuncCallingConv());
-
cir::CallOp call = builder.createCallOp(loc, callee, args);
assert(call->getNumResults() <= 1 &&
"runtime functions have at most 1 result");
@@ -1149,8 +1147,6 @@ void CIRGenFunction::emitCallArgs(
AbstractCallee callee, unsigned paramsToSkip) {
llvm::SmallVector<QualType, 16> argTypes;
- assert(!cir::MissingFeatures::opCallCallConv());
-
// First, if a prototype was provided, use those argument types.
bool isVariadic = false;
if (prototype.p) {
@@ -1158,7 +1154,6 @@ void CIRGenFunction::emitCallArgs(
const auto *fpt = cast<const FunctionProtoType *>(prototype.p);
isVariadic = fpt->isVariadic();
- assert(!cir::MissingFeatures::opCallCallConv());
argTypes.assign(fpt->param_type_begin() + paramsToSkip,
fpt->param_type_end());
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index fb7da9e414139..8ac47757c03ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
#include "clang/AST/CanonicalType.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/TrailingObjects.h"
@@ -72,6 +73,16 @@ class RequiredArgs {
class CIRGenFunctionInfo final
: public llvm::FoldingSetNode,
private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {
+ /// The cir::CallingConv to use for this function (as specified by the user).
+ cir::CallingConv callingConvention : 8;
+
+ /// The cir::CallingConv to actually use for this function, which may depend
+ /// on the ABI.
+ cir::CallingConv effectiveCallingConvention : 8;
+
+ /// The clang::CallingConv that this was originally created with.
+ unsigned astCallingConvention : 6;
+
// Whether this function has noreturn.
LLVM_PREFERRED_TYPE(bool)
unsigned noReturn : 1;
@@ -90,13 +101,15 @@ class CIRGenFunctionInfo final
// here instead of explicit false/0.
return FunctionType::ExtInfo(
isNoReturn(), /*getHasRegParm=*/false, /*getRegParm=*/false,
- /*getASTCallingConvention=*/CallingConv(0), /*isReturnsRetained=*/false,
+ /*getASTCallingConvention=*/getASTCallingConvention(),
+ /*isReturnsRetained=*/false,
/*isNoCallerSavedRegs=*/false, /*isNoCfCheck=*/false,
/*isCmseNSCall=*/false);
}
public:
- static CIRGenFunctionInfo *create(FunctionType::ExtInfo info,
+ static CIRGenFunctionInfo *create(cir::CallingConv cirCC,
+ FunctionType::ExtInfo info,
CanQualType resultType,
llvm::ArrayRef<CanQualType> argTypes,
RequiredArgs required);
@@ -115,6 +128,7 @@ class CIRGenFunctionInfo final
static void Profile(llvm::FoldingSetNodeID &id, FunctionType::ExtInfo info,
RequiredArgs required, CanQualType resultType,
llvm::ArrayRef<CanQualType> argTypes) {
+ id.AddInteger(info.getCC());
id.AddBoolean(info.getNoReturn());
id.AddBoolean(required.getOpaqueData());
resultType.Profile(id);
@@ -162,6 +176,20 @@ class CIRGenFunctionInfo final
}
bool isNoReturn() const { return noReturn; }
+
+ /// getASTCallingConvention - Return the AST-specified calling convention.
+ clang::CallingConv getASTCallingConvention() const {
+ return clang::CallingConv(astCallingConvention);
+ }
+
+ /// getCallingConvention - Return the user specified calling convention.
+ cir::CallingConv getCallingConvention() const { return callingConvention; }
+
+ /// getEffectiveCallingConvention - Return the actual calling convention to
+ /// use, which may depend on the ABI.
+ cir::CallingConv getEffectiveCallingConvention() const {
+ return effectiveCallingConvention;
+ }
};
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index aca2278c3876c..6c59bf1ffadc5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -1891,18 +1891,12 @@ mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf) {
// Prototype: void __cxa_bad_cast();
- // TODO(cir): set the calling convention of the runtime function.
- assert(!cir::MissingFeatures::opFuncCallingConv());
-
cir::FuncType fnTy =
cgf.getBuilder().getFuncType({}, cgf.getBuilder().getVoidTy());
return cgf.cgm.createRuntimeFunction(fnTy, "__cxa_bad_cast");
}
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc) {
- // TODO(cir): set the calling convention to the runtime function.
- assert(!cir::MissingFeatures::opFuncCallingConv());
-
cgf.emitRuntimeCall(loc, getBadCastFn(cgf));
cir::UnreachableOp::create(cgf.getBuilder(), loc);
cgf.getBuilder().clearInsertionPoint();
@@ -1981,9 +1975,6 @@ static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf) {
assert(!cir::MissingFeatures::opFuncWillReturn());
assert(!cir::MissingFeatures::opFuncReadOnly());
- // TODO(cir): set the calling convention of the runtime function.
- assert(!cir::MissingFeatures::opFuncCallingConv());
-
cir::FuncType FTy = cgf.getBuilder().getFuncType(
{voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
return cgf.cgm.createRuntimeFunction(FTy, "__dynamic_cast");
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 007d501f25014..f776206edeabb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -2232,11 +2232,7 @@ void CIRGenModule::setCIRFunctionAttributes(GlobalDecl globalDecl,
// TODO(cir): Check X86_VectorCall incompatibility wiht WinARM64EC
- // TODO(cir): typically the calling conv is set right here, but since
- // cir::CallingConv is empty and we've not yet added calling-conv to FuncOop,
- // this isn't really useful here. This should call func.setCallingConv/etc
- // later.
- assert(!cir::MissingFeatures::opFuncCallingConv());
+ func.setCallingConv(callingConv);
}
void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl,
@@ -2638,7 +2634,6 @@ cir::FuncOp CIRGenModule::createRuntimeFunction(cir::FuncType ty,
if (entry) {
// TODO(cir): set the attributes of the function.
assert(!cir::MissingFeatures::setLLVMFunctionFEnvAttributes());
- assert(!cir::MissingFeatures::opFuncCallingConv());
setWindowsItaniumDLLImport(*this, isLocal, entry, name);
entry.setDSOLocal(true);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index c4f745b492102..3562e4a0d8223 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -10,6 +10,9 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+
#include <cassert>
using namespace clang;
@@ -29,6 +32,23 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const {
return *builder.getContext();
}
+cir::CallingConv
+CIRGenTypes::ClangCallConvToCIRCallConv(clang::CallingConv CC) {
+ switch (CC) {
+ case CC_C:
+ return cir::CallingConv::C;
+ case CC_DeviceKernel:
+ return cgm.getTargetCIRGenInfo().getDeviceKernelCallingConv();
+ case CC_SpirFunction:
+ return cir::CallingConv::SpirFunction;
+ default:
+ cgm.errorNYI((llvm::Twine("unsupported calling convention: ") +
+ FunctionType::getNameForCallConv(CC))
+ .str());
+ return cir::CallingConv::C;
+ }
+}
+
/// Return true if the specified type in a function parameter or result position
/// can be converted to a CIR type at this point. This boils down to being
/// whether it is complete, as well as whether we've temporarily deferred
@@ -683,10 +703,9 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
return *fi;
}
- assert(!cir::MissingFeatures::opCallCallConv());
-
// Construction the function info. We co-allocate the ArgInfos.
- fi = CIRGenFunctionInfo::create(info, returnType, argTypes, required);
+ cir::CallingConv cirCC = ClangCallConvToCIRCallConv(info.getCC());
+ fi = CIRGenFunctionInfo::create(cirCC, info, returnType, argTypes, required);
functionInfos.InsertNode(fi, insertPos);
return *fi;
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h
index e36e81b07684b..a06fe570d03e2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h
@@ -120,6 +120,9 @@ class CIRGenTypes {
const CIRGenRecordLayout &getCIRGenRecordLayout(const clang::RecordDecl *rd);
+ /// Convert clang calling convention to CIR calling convention.
+ cir::CallingConv ClangCallConvToCIRCallConv(clang::CallingConv cc);
+
/// Convert type T into an mlir::Type. This differs from convertType in that
/// it is used to convert to the memory representation for a type. For
/// example, the scalar representation for bool is i1, but the memory
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp
index 5a0c854db9125..172450fdb7fd3 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -67,6 +67,10 @@ class NVPTXTargetCIRGenInfo : public TargetCIRGenInfo {
public:
NVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
: TargetCIRGenInfo(std::make_unique<NVPTXABIInfo>(cgt)) {}
+
+ cir::CallingConv getDeviceKernelCallingConv() const override {
+ return cir::CallingConv::PTXKernel;
+ }
};
} // namespace
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h
index 79325c2d35c4d..dad0756d352e7 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.h
+++ b/clang/lib/CIR/CodeGen/TargetInfo.h
@@ -52,6 +52,11 @@ class TargetCIRGenInfo {
return {};
}
+ /// Get CIR calling convention for functions using CC_DeviceKernel.
+ virtual cir::CallingConv getDeviceKernelCallingConv() const {
+ return cir::CallingConv::C;
+ }
+
/// Determine whether a call to an unprototyped functions under
/// the given calling convention should use the variadic
/// convention or the non-variadic convention.
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 9574851a0ae2c..d2a9a9a44052a 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -132,6 +132,7 @@ template <typename Ty> struct EnumTraits {};
REGISTER_ENUM_TYPE(GlobalLinkageKind);
REGISTER_ENUM_TYPE(VisibilityKind);
+REGISTER_ENUM_TYPE(CallingConv);
REGISTER_ENUM_TYPE(SideEffect);
} // namespace
@@ -882,16 +883,30 @@ static mlir::ParseResult parseCallCommon(mlir::OpAsmParser &parser,
if (parser.resolveOperands(ops, opsFnTy.getInputs(), opsLoc, resul...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/181170
More information about the cfe-commits
mailing list