https://github.com/skc7 created https://github.com/llvm/llvm-project/pull/220197
**Summary:** - Route the amdgpu triple to a new `CallConvTarget::AMDGPU` and drive the LLVM ABI library's AMDGPU classifier from CallConvLowering. **Changes:** - The X86-only classifier helpers are generalized to any target and thread the calling convention. - Adds an `abi-lowering/amdgpu-scalars.cir` test for the supported cases. - Opts `amdgcn-buffer-rsrc-type.hip` out of call-conv-lowering (TODO) until the bridge supports its direct-in-registers aggregate return. Assisted by: Claude Opus 4.8 >From c1302daffefcefc3cc7874a63093bdcd1811c981 Mon Sep 17 00:00:00 2001 From: skc7 <[email protected]> Date: Tue, 1 Sep 2026 14:31:15 +0530 Subject: [PATCH] [CIR] Wire AMDGPU into the call-convention lowering pass --- clang/include/clang/CIR/Dialect/Passes.h | 2 +- clang/include/clang/CIR/Dialect/Passes.td | 4 +- .../Transforms/CallConvLoweringPass.cpp | 140 +++++++++++------- clang/lib/CIR/Lowering/CIRPasses.cpp | 6 +- .../CodeGenHIP/amdgcn-buffer-rsrc-type.hip | 8 +- .../abi-lowering/amdgpu-scalars.cir | 105 +++++++++++++ .../x86_64-lang-addrspace-nyi.cir | 2 +- 7 files changed, 204 insertions(+), 63 deletions(-) create mode 100644 clang/test/CIR/Transforms/abi-lowering/amdgpu-scalars.cir diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h index 674f2180c27ab..796efff8e4d7c 100644 --- a/clang/include/clang/CIR/Dialect/Passes.h +++ b/clang/include/clang/CIR/Dialect/Passes.h @@ -20,7 +20,7 @@ namespace cir { /// The ABI target whose calling-convention rules drive CallConvLowering. /// None is the unset state used when the pass runs in classification-attr /// mode instead of selecting a target. -enum class CallConvTarget { None, Test, X86_64 }; +enum class CallConvTarget { None, Test, X86_64, AMDGPU }; } // namespace cir namespace clang { diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td index b983cfe59112a..fd2ae1003d35c 100644 --- a/clang/include/clang/CIR/Dialect/Passes.td +++ b/clang/include/clang/CIR/Dialect/Passes.td @@ -246,7 +246,9 @@ def CallConvLowering : Pass<"cir-call-conv-lowering", "mlir::ModuleOp"> { clEnumValN(cir::CallConvTarget::Test, "test", "MLIR test ABI target"), clEnumValN(cir::CallConvTarget::X86_64, "x86_64", - "x86_64 System V") + "x86_64 System V"), + clEnumValN(cir::CallConvTarget::AMDGPU, "amdgpu", + "AMDGPU") )}]>, Option<"classificationAttr", "classification-attr", "std::string", /*default=*/"\"\"", diff --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp index 11c2a66dba7b5..c1c69947d55c5 100644 --- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp @@ -80,7 +80,7 @@ namespace { // bit-field access unit, a record holding an empty-for-ABI member that // occupies bytes or a zero-sized one off its own alignment, a union no member // of which spans its declared size, and a union with an empty-record member -// are reported NYI by classifyX86_64Function so an unsupported signature +// are reported NYI by classifyAbiSignature so an unsupported signature // fails the pass instead of being misclassified. //===----------------------------------------------------------------------===// @@ -142,7 +142,7 @@ static bool reachesNamedBitFieldUnit(mlir::Type ty) { /// whose members are all themselves supported, or an array of a supported /// element type. Also a `_Complex`, or a fixed-width vector, of a supported /// element type. Everything else is reported NYI at the reject() choke point -/// in classifyX86_64Function. +/// in classifyAbiSignature. static bool isSupportedType(mlir::Type ty, const DataLayout &dl) { // A pointer is only handled in the default address space (null) or an // already-lowered target address space. A LangAddressSpaceAttr must be @@ -314,7 +314,7 @@ static mlir::Type abiTypeToCIR(const llvm::abi::Type *ty, MLIRContext *ctx) { .Default([](const llvm::abi::Type *) -> mlir::Type { return nullptr; }); } -/// Map a CIR type to an llvm::abi::Type. classifyX86_64Function pre-filters +/// Map a CIR type to an llvm::abi::Type. classifyAbiSignature pre-filters /// the signature, so only the scalar and struct/array types handled here can /// reach this function. static const llvm::abi::Type *mapCIRType(mlir::Type type, @@ -442,7 +442,7 @@ static const llvm::abi::Type *mapCIRType(mlir::Type type, }) .Default([](mlir::Type) -> const llvm::abi::Type * { llvm_unreachable( - "mapCIRType: type not pre-filtered by classifyX86_64Function"); + "mapCIRType: type not pre-filtered by classifyAbiSignature"); }); } @@ -535,20 +535,31 @@ static llvm::abi::RequiredArgs requiredArgs(cir::FuncType fnTy) { return llvm::abi::RequiredArgs(fnTy.getNumInputs()); } -/// Classify an x86_64 SysV signature (return type + argument types) using the -/// LLVM ABI library. Shared by the cir.func path, the variadic-call path and -/// the indirect-call path (the latter classifies from the callee function +/// Map a cir.func calling convention to the llvm::CallingConv the ABI +/// classifier keys on. Only the AMDGPU kernel convention changes +/// classification today; every other convention is classified as C. +static llvm::CallingConv::ID abiCallingConv(cir::CallingConv cc) { + if (cc == cir::CallingConv::AMDGPUKernel) + return llvm::CallingConv::AMDGPU_KERNEL; + return llvm::CallingConv::C; +} + +/// Classify a signature (return type + argument types) for \p targetInfo using +/// the LLVM ABI library. Shared by the cir.func path, the variadic-call path +/// and the indirect-call path (the latter classifies from the callee function /// pointer's pointee FuncType). \p required marks where the declared /// parameters in \p inputs end. The classifier treats every argument past that -/// point as passed through an ellipsis. Returns std::nullopt and emits an NYI -/// error via \p emitError if the signature uses a type the bridge does not -/// handle yet. -static std::optional<FunctionClassification> classifyX86_64Signature( - mlir::Type retCIR, mlir::TypeRange inputs, llvm::abi::RequiredArgs required, - MLIRContext *ctx, const DataLayout &dl, - mlir::abi::ABITypeMapper &typeMapper, - const llvm::abi::TargetInfo &targetInfo, ModuleOp modOp, - llvm::function_ref<mlir::InFlightDiagnostic()> emitError) { +/// point as passed through an ellipsis. \p callConv selects the ABI convention +/// (e.g. AMDGPU_KERNEL), which some targets classify differently. Returns +/// std::nullopt and emits an NYI error via \p emitError if the signature uses a +/// type the bridge does not handle yet. +static std::optional<FunctionClassification> +classifyAbiSignature(mlir::Type retCIR, mlir::TypeRange inputs, + llvm::abi::RequiredArgs required, MLIRContext *ctx, + const DataLayout &dl, mlir::abi::ABITypeMapper &typeMapper, + const llvm::abi::TargetInfo &targetInfo, + llvm::CallingConv::ID callConv, ModuleOp modOp, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) { assert(retCIR && "signature return type must be non-null"); assert((!required.allowsOptionalArgs() || required.getNumRequiredArgs() <= inputs.size()) && @@ -558,9 +569,8 @@ static std::optional<FunctionClassification> classifyX86_64Signature( auto reject = [&](mlir::Type t) -> bool { if (isSupportedType(t, dl)) return false; - emitError() - << "x86_64 calling-convention lowering not yet implemented for type " - << t; + emitError() << "calling-convention lowering not yet implemented for type " + << t; return true; }; if (!voidRet && reject(retCIR)) @@ -576,15 +586,15 @@ static std::optional<FunctionClassification> classifyX86_64Signature( for (mlir::Type a : inputs) argAbi.push_back(mapCIRType(a, typeMapper, dl, modOp)); - std::unique_ptr<llvm::abi::FunctionInfo> fi = llvm::abi::FunctionInfo::create( - llvm::CallingConv::C, retAbi, argAbi, required); + std::unique_ptr<llvm::abi::FunctionInfo> fi = + llvm::abi::FunctionInfo::create(callConv, retAbi, argAbi, required); targetInfo.computeInfo(*fi); // convertABIArgInfo returns nullopt when the classifier picks a coercion this // bridge cannot represent. auto nyiCoercion = [&](mlir::Type t) { - emitError() << "x86_64 calling-convention lowering not yet " - "implemented for the ABI coercion of type " + emitError() << "calling-convention lowering not yet implemented for the " + "ABI coercion of type " << t; }; @@ -636,19 +646,19 @@ static llvm::abi::X86AVXABILevel funcAvxLevel(cir::FuncOp func, return avx ? std::max(base, llvm::abi::X86AVXABILevel::AVX) : base; } -/// Classify a cir.func for x86_64 SysV using the LLVM ABI library. Returns +/// Classify a cir.func for \p targetInfo using the LLVM ABI library. Returns /// std::nullopt and emits an NYI error if the signature uses a type the bridge /// does not handle yet. static std::optional<FunctionClassification> -classifyX86_64Function(cir::FuncOp func, const DataLayout &dl, - mlir::abi::ABITypeMapper &typeMapper, - const llvm::abi::TargetInfo &targetInfo, - ModuleOp modOp) { +classifyAbiFunction(cir::FuncOp func, const DataLayout &dl, + mlir::abi::ABITypeMapper &typeMapper, + const llvm::abi::TargetInfo &targetInfo, ModuleOp modOp) { cir::FuncType fnTy = func.getFunctionType(); - return classifyX86_64Signature(fnTy.getReturnType(), fnTy.getInputs(), - requiredArgs(fnTy), func->getContext(), dl, - typeMapper, targetInfo, modOp, - [&]() { return func.emitOpError(); }); + return classifyAbiSignature(fnTy.getReturnType(), fnTy.getInputs(), + requiredArgs(fnTy), func->getContext(), dl, + typeMapper, targetInfo, + abiCallingConv(func.getCallingConv()), modOp, + [&]() { return func.emitOpError(); }); } /// Classify a call that passes arguments through an ellipsis. The callee's @@ -658,17 +668,19 @@ classifyX86_64Function(cir::FuncOp func, const DataLayout &dl, /// small struct is passed in registers early in the list and in memory once /// the integer registers are gone. Classifying from the call's operands /// rather than the callee's signature is what makes that accounting right. -static std::optional<FunctionClassification> classifyX86_64VariadicCall( - cir::CIRCallOpInterface call, cir::FuncType calleeTy, const DataLayout &dl, - mlir::abi::ABITypeMapper &typeMapper, - const llvm::abi::TargetInfo &targetInfo, ModuleOp modOp) { +static std::optional<FunctionClassification> +classifyAbiVariadicCall(cir::CIRCallOpInterface call, cir::FuncType calleeTy, + const DataLayout &dl, + mlir::abi::ABITypeMapper &typeMapper, + const llvm::abi::TargetInfo &targetInfo, + llvm::CallingConv::ID callConv, ModuleOp modOp) { assert(calleeTy.isVarArg() && "only a variadic callee can take more operands than it declares"); Operation *op = call.getOperation(); - return classifyX86_64Signature( + return classifyAbiSignature( calleeTy.getReturnType(), call.getArgOperands().getTypes(), requiredArgs(calleeTy), op->getContext(), dl, typeMapper, targetInfo, - modOp, [&]() { return op->emitOpError(); }); + callConv, modOp, [&]() { return op->emitOpError(); }); } #ifndef NDEBUG @@ -810,10 +822,18 @@ void CallConvLoweringPass::runOnOperation() { static constexpr unsigned numAvxLevels = static_cast<unsigned>(llvm::abi::X86AVXABILevel::Last) + 1; bool isX86 = target == cir::CallConvTarget::X86_64; - std::optional<mlir::abi::ABITypeMapper> x86TypeMapper; + bool isAMDGPU = target == cir::CallConvTarget::AMDGPU; + // The x86_64 and AMDGPU drivers classify with the LLVM ABI library and share + // the type mapper; the test and classification-attr drivers do neither. + bool useAbiClassifier = isX86 || isAMDGPU; + std::optional<mlir::abi::ABITypeMapper> abiTypeMapper; std::array<std::unique_ptr<llvm::abi::TargetInfo>, numAvxLevels> x86Targets; - if (isX86) - x86TypeMapper.emplace(dl); + std::unique_ptr<llvm::abi::TargetInfo> amdgpuTarget; + if (useAbiClassifier) + abiTypeMapper.emplace(dl); + if (isAMDGPU) + amdgpuTarget = + llvm::abi::createAMDGPUTargetInfo(abiTypeMapper->getTypeBuilder()); auto x86TargetFor = [&](llvm::abi::X86AVXABILevel level) -> const llvm::abi::TargetInfo & { assert(static_cast<unsigned>(level) < numAvxLevels && @@ -822,7 +842,7 @@ void CallConvLoweringPass::runOnOperation() { x86Targets[static_cast<unsigned>(level)]; if (!slot) slot = llvm::abi::createX86_64TargetInfo( - x86TypeMapper->getTypeBuilder(), level, + abiTypeMapper->getTypeBuilder(), level, /*Has64BitPointers=*/true, x86AbiCompat); return *slot; }; @@ -832,6 +852,13 @@ void CallConvLoweringPass::runOnOperation() { return baseAvxLevel; return funcAvxLevel(func, baseAvxLevel); }; + // The classifier to use for a function/call reached from \p func. AMDGPU has + // a single classifier; x86_64 picks the one matching func's AVX level. + auto targetInfoFor = [&](cir::FuncOp func) -> const llvm::abi::TargetInfo & { + if (isAMDGPU) + return *amdgpuTarget; + return x86TargetFor(avxLevelFor(func)); + }; // Classify every cir.func up front. No IR mutation happens here, so // later walks can consult any function's classification regardless of @@ -840,9 +867,9 @@ void CallConvLoweringPass::runOnOperation() { bool anyFailed = false; moduleOp.walk([&](cir::FuncOp f) { std::optional<FunctionClassification> fc; - if (isX86) - fc = classifyX86_64Function(f, dl, *x86TypeMapper, - x86TargetFor(avxLevelFor(f)), moduleOp); + if (useAbiClassifier) + fc = classifyAbiFunction(f, dl, *abiTypeMapper, targetInfoFor(f), + moduleOp); else fc = classifyFunction(f, dl, target, classificationAttr); if (!fc) { @@ -879,11 +906,12 @@ void CallConvLoweringPass::runOnOperation() { return; callers[callee].push_back(op); - // Only the x86_64 driver classifies per call site. Under the other + // Only the ABI-library drivers classify per call site. Under the other // drivers the classification comes from a fixed per-function source, so // such a call stays short a classification and rewriteCallSite reports it. cir::FuncType calleeTy = callee.getFunctionType(); - if (!isX86 || call.getNumArgOperands() <= calleeTy.getNumInputs()) + if (!useAbiClassifier || + call.getNumArgOperands() <= calleeTy.getNumInputs()) return; // A callee declared without a prototype also takes more operands than it // declares, and the verifier allows it. Those extra arguments are named @@ -900,9 +928,9 @@ void CallConvLoweringPass::runOnOperation() { // Classic instead arranges every call site from the caller and reports a // caller whose level disagrees with its callee in checkFunctionCallABI, // which has no equivalent here yet. - std::optional<FunctionClassification> fc = - classifyX86_64VariadicCall(call, calleeTy, dl, *x86TypeMapper, - x86TargetFor(avxLevelFor(callee)), moduleOp); + std::optional<FunctionClassification> fc = classifyAbiVariadicCall( + call, calleeTy, dl, *abiTypeMapper, targetInfoFor(callee), + abiCallingConv(callee.getCallingConv()), moduleOp); if (!fc) { anyFailed = true; return; @@ -995,13 +1023,13 @@ void CallConvLoweringPass::runOnOperation() { [&](mlir::TypeRange argTypes) -> std::optional<FunctionClassification> { // A callee resolved at run time carries no features of its own, so the // level comes from the function containing the call, which is the - // declaration classic arranges every call site from. - if (isX86) - return classifyX86_64Signature( + // declaration classic arranges every call site from. An indirect callee + // is an ordinary function pointer, so it uses the C convention. + if (useAbiClassifier) + return classifyAbiSignature( funcTy.getReturnType(), argTypes, requiredArgs(funcTy), ctx, dl, - *x86TypeMapper, - x86TargetFor(avxLevelFor(c->getParentOfType<cir::FuncOp>())), - moduleOp, [&]() { return c->emitOpError(); }); + *abiTypeMapper, targetInfoFor(c->getParentOfType<cir::FuncOp>()), + llvm::CallingConv::C, moduleOp, [&]() { return c->emitOpError(); }); return withReturnVoidness( mlir::abi::test::classify(argTypes, funcTy.getReturnType(), dl), funcTy.getReturnType()); diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index 64d82dd4e7301..6b86ab69fd614 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -26,6 +26,8 @@ namespace cir { static CallConvTarget getCallConvTarget(const llvm::Triple &triple) { if (triple.getArch() == llvm::Triple::x86_64) return CallConvTarget::X86_64; + if (triple.isAMDGPU()) + return CallConvTarget::AMDGPU; return CallConvTarget::None; } @@ -115,8 +117,8 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, if (enableCallConvLowering) { // CallConvLowering rewrites signatures and call sites using the classifier, // so it must run after CXXABILowering has lowered C++ ABI types to plain - // records the classifier can handle. Only the x86_64 System V classifier - // is implemented; other targets are left unchanged. + // records the classifier can handle. Only the x86_64 System V and AMDGPU + // classifiers are implemented; other targets are left unchanged. const clang::TargetInfo &targetInfo = astContext.getTargetInfo(); CallConvTarget target = getCallConvTarget(targetInfo.getTriple()); if (target != CallConvTarget::None) diff --git a/clang/test/CIR/CodeGenHIP/amdgcn-buffer-rsrc-type.hip b/clang/test/CIR/CodeGenHIP/amdgcn-buffer-rsrc-type.hip index e03fa4db5c20d..0045a731c579f 100644 --- a/clang/test/CIR/CodeGenHIP/amdgcn-buffer-rsrc-type.hip +++ b/clang/test/CIR/CodeGenHIP/amdgcn-buffer-rsrc-type.hip @@ -1,12 +1,16 @@ #include "../CodeGenCUDA/Inputs/cuda.h" // REQUIRES: amdgpu-registered-target + +// TODO(cir): drop -fno-clangir-call-conv-lowering once CallConvLowering +// supports the AMDGPU direct-in-registers aggregate return of a buffer +// resource struct. // RUN: %clang_cc1 -triple amdgpu11.00-amd-amdhsa -x hip -std=c++11 -fclangir \ -// RUN: -fcuda-is-device -emit-cir %s -o %t.cir +// RUN: -fcuda-is-device -fno-clangir-call-conv-lowering -emit-cir %s -o %t.cir // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s // RUN: %clang_cc1 -triple amdgpu11.00-amd-amdhsa -x hip -std=c++11 -fclangir \ -// RUN: -fcuda-is-device -emit-llvm %s -o %t-cir.ll +// RUN: -fcuda-is-device -fno-clangir-call-conv-lowering -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s // RUN: %clang_cc1 -triple amdgpu11.00-amd-amdhsa -x hip -std=c++11 \ diff --git a/clang/test/CIR/Transforms/abi-lowering/amdgpu-scalars.cir b/clang/test/CIR/Transforms/abi-lowering/amdgpu-scalars.cir new file mode 100644 index 0000000000000..5b9049e119757 --- /dev/null +++ b/clang/test/CIR/Transforms/abi-lowering/amdgpu-scalars.cir @@ -0,0 +1,105 @@ +// RUN: cir-opt %s -cir-call-conv-lowering=target=amdgpu | FileCheck %s + +!s8i = !cir.int<s, 8> +!s16i = !cir.int<s, 16> +!u16i = !cir.int<u, 16> +!s32i = !cir.int<s, 32> +!s64i = !cir.int<s, 64> + +!rec_E0 = !cir.struct<"E0" {}> +!rec_Pair16 = !cir.struct<"Pair16" {data !s16i, data !s16i}> + +module attributes { + dlti.dl_spec = #dlti.dl_spec< + #dlti.dl_entry<i1, dense<8>: vector<2xi64>>, + #dlti.dl_entry<i8, dense<8>: vector<2xi64>>, + #dlti.dl_entry<i16, dense<16>: vector<2xi64>>, + #dlti.dl_entry<i32, dense<32>: vector<2xi64>>, + #dlti.dl_entry<i64, dense<64>: vector<2xi64>>> +} { + + // Register-sized integers are Direct: signature and call sites unchanged. + cir.func @passthrough(%arg0: !s32i, %arg1: !s64i) -> !s32i { + cir.return %arg0 : !s32i + } + + // CHECK: cir.func{{.*}} @passthrough(%arg0: !s32i, %arg1: !s64i) -> !s32i + // CHECK-NEXT: cir.return %arg0 : !s32i + + // Floating-point scalars are Direct. + cir.func @floats(%arg0: !cir.float, %arg1: !cir.double) -> !cir.double { + cir.return %arg1 : !cir.double + } + + // CHECK: cir.func{{.*}} @floats(%arg0: !cir.float, %arg1: !cir.double) -> !cir.double + + // Pointers are Direct. + cir.func @take_ptr(%arg0: !cir.ptr<!s32i>) -> !cir.ptr<!s32i> { + cir.return %arg0 : !cir.ptr<!s32i> + } + + // CHECK: cir.func{{.*}} @take_ptr(%arg0: !cir.ptr<!s32i>) -> !cir.ptr<!s32i> + + // Signed sub-register integer is sign-extended. + cir.func @take_s8(%arg0: !s8i) { + cir.return + } + + // CHECK: cir.func{{.*}} @take_s8(%arg0: !s8i {llvm.signext}) + + // Unsigned sub-register integer is zero-extended. + cir.func @take_u16(%arg0: !u16i) { + cir.return + } + + // CHECK: cir.func{{.*}} @take_u16(%arg0: !u16i {llvm.zeroext}) + + // bool is zero-extended. + cir.func @take_bool(%arg0: !cir.bool) { + cir.return + } + + // CHECK: cir.func{{.*}} @take_bool(%arg0: !cir.bool {llvm.zeroext}) + + // Call site picks up the same extension attribute on the operand. + cir.func @call_s8(%arg0: !s8i) { + cir.call @take_s8(%arg0) : (!s8i) -> () + cir.return + } + + // CHECK: cir.call @take_s8(%arg0) : (!s8i {llvm.signext}) -> () + + // A sub-register integer return is also extended, not just arguments. + cir.func @ret_s8() -> !s8i { + %0 = cir.const #cir.int<0> : !s8i + cir.return %0 : !s8i + } + + // CHECK: cir.func{{.*}} @ret_s8() -> (!s8i {llvm.signext}) + + // A zero-field record classifies as Ignore: the empty argument is dropped + // and the real argument shifts down to the first slot. + cir.func @take_empty(%arg0: !rec_E0, %arg1: !s32i) -> !s32i { + cir.return %arg1 : !s32i + } + + // CHECK: cir.func{{.*}} @take_empty(%arg0: !s32i) -> !s32i + // CHECK-NEXT: cir.return %arg0 : !s32i + + // A small aggregate (<= 32 bits) is packed into a single i32 register. + cir.func @takes_small(%arg0: !rec_Pair16) { + %0 = cir.alloca "p" align(4) : !cir.ptr<!rec_Pair16> + cir.store %arg0, %0 : !rec_Pair16, !cir.ptr<!rec_Pair16> + cir.return + } + + // CHECK: cir.func{{.*}} @takes_small(%{{.*}}: !u32i) + + // A kernel scalar argument stays Direct: the AMDGPU_KERNEL convention is + // routed to the kernel classifier and the signature is unchanged. + cir.func @kernel_scalar(%arg0: !s32i) cc(amdgpu_kernel) { + cir.return + } + + // CHECK: cir.func{{.*}} @kernel_scalar(%arg0: !s32i){{.*}}cc(amdgpu_kernel) +} diff --git a/clang/test/CIR/Transforms/abi-lowering/x86_64-lang-addrspace-nyi.cir b/clang/test/CIR/Transforms/abi-lowering/x86_64-lang-addrspace-nyi.cir index a8350b421757d..285df67e53c83 100644 --- a/clang/test/CIR/Transforms/abi-lowering/x86_64-lang-addrspace-nyi.cir +++ b/clang/test/CIR/Transforms/abi-lowering/x86_64-lang-addrspace-nyi.cir @@ -15,4 +15,4 @@ module attributes { } -// CHECK: op x86_64 calling-convention lowering not yet implemented for type +// CHECK: op calling-convention lowering not yet implemented for type _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
