llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Chaitanya (skc7) <details> <summary>Changes</summary> **Summary:** - Mirror classic `ABIArgInfo::CanBeFlattened` and forward it through the CIR bridge so a target can keep a multi-field struct coerce intact instead of flattening it into N scalar arguments. Required for AMDGPU kernel and variadic arguments, which set `CanBeFlattened=false`. **Changes:** - Added a `CanBeFlattened : 1` bitfield to `llvm::abi::ArgInfo`, a `CanBeFlattened` parameter on `getDirect(...)` and `getCanBeFlattened()` accessor. - Forward `info.getCanBeFlattened()` into `ArgClassification` for Direct classifications in `convertABIArgInfo` in CIR `CallConvLoweringPass.cpp`. - `llvm/unittests/ABI/FunctionInfoTest.cpp` unit tests for the accessor. Assisted by: Claude Opus 4.8 --- Full diff: https://github.com/llvm/llvm-project/pull/220579.diff 5 Files Affected: - (modified) clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp (+7-4) - (modified) llvm/include/llvm/ABI/FunctionInfo.h (+12-2) - (modified) llvm/unittests/ABI/CMakeLists.txt (+1) - (added) llvm/unittests/ABI/FunctionInfoTest.cpp (+43) - (modified) llvm/utils/gn/secondary/llvm/unittests/ABI/BUILD.gn (+1) ``````````diff diff --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp index dbcf19da5c826..45d723e227126 100644 --- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp @@ -481,9 +481,10 @@ static const llvm::abi::Type *mapCIRType(mlir::Type type, /// three cases where the value has to be rebuilt on the wire: an aggregate /// unpacked into the register(s) holding it, a scalar too wide for one register /// split into a tuple of them, and a scalar the classifier widens to fill its -/// eightbyte. getDirect keeps canFlatten set so the rewriter can split a -/// multi-field coerced struct into individual wire arguments. Any other scalar -/// passes in its natural CIR type, which a null coercion denotes. A coercion +/// eightbyte. canFlatten follows the classifier's CanBeFlattened, so the +/// rewriter splits a multi-field coerced struct into individual wire arguments +/// unless the classifier asked to keep it intact. Any other scalar passes in +/// its natural CIR type, which a null coercion denotes. A coercion /// this bridge cannot represent yields std::nullopt so the caller reports NYI /// rather than silently passing the value unchanged. /// @@ -536,7 +537,9 @@ convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx, // trip for nothing. if (comparesAgainstCoerce && coerced == origTy) return ArgClassification::getDirect(nullptr); - return ArgClassification::getDirect(coerced); + ArgClassification classified = ArgClassification::getDirect(coerced); + classified.canFlatten = info.getCanBeFlattened(); + return classified; } if (info.isExtend()) { if (isa_and_present<cir::BoolType>(origTy)) diff --git a/llvm/include/llvm/ABI/FunctionInfo.h b/llvm/include/llvm/ABI/FunctionInfo.h index caedafcbe9d22..f4c20f64677c4 100644 --- a/llvm/include/llvm/ABI/FunctionInfo.h +++ b/llvm/include/llvm/ABI/FunctionInfo.h @@ -71,10 +71,11 @@ class ArgInfo { bool ZeroExt : 1; bool IndirectByVal : 1; bool IndirectRealign : 1; + bool CanBeFlattened : 1; ArgInfo(Kind K = Direct) : TheKind(K), SignExt(false), ZeroExt(false), IndirectByVal(false), - IndirectRealign(false) {} + IndirectRealign(false), CanBeFlattened(true) {} public: /// \param T The type to coerce to. If null, the argument's original type is @@ -85,12 +86,16 @@ class ArgInfo { /// return value on x86-64). /// \param Align Override for the argument's alignment. If absent, the /// default alignment for \p T is used. + /// \param CanBeFlattened Whether a multi-field struct coerce type may be + /// expanded into one argument per field. False keeps it intact. static ArgInfo getDirect(const Type *T = nullptr, unsigned Offset = 0, - MaybeAlign Align = std::nullopt) { + MaybeAlign Align = std::nullopt, + bool CanBeFlattened = true) { ArgInfo AI(Direct); AI.CoercionType = T; AI.Alignment = Align; AI.DirectAttr.Offset = Offset; + AI.CanBeFlattened = CanBeFlattened; return AI; } @@ -197,6 +202,11 @@ class ArgInfo { assert((isDirect() || isExtend()) && "Invalid Kind!"); return CoercionType; } + + bool getCanBeFlattened() const { + assert(isDirect() && "Not a direct kind"); + return CanBeFlattened; + } }; struct ArgEntry { diff --git a/llvm/unittests/ABI/CMakeLists.txt b/llvm/unittests/ABI/CMakeLists.txt index a26da474bd83a..16eb400c279c3 100644 --- a/llvm/unittests/ABI/CMakeLists.txt +++ b/llvm/unittests/ABI/CMakeLists.txt @@ -6,5 +6,6 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(ABITests AArch64TargetInfoTest.cpp + FunctionInfoTest.cpp X86TargetInfoTest.cpp ) diff --git a/llvm/unittests/ABI/FunctionInfoTest.cpp b/llvm/unittests/ABI/FunctionInfoTest.cpp new file mode 100644 index 0000000000000..f43557b32ce1d --- /dev/null +++ b/llvm/unittests/ABI/FunctionInfoTest.cpp @@ -0,0 +1,43 @@ +//===- FunctionInfoTest.cpp - ArgInfo unit tests --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ABI/FunctionInfo.h" +#include "llvm/ABI/Types.h" +#include "llvm/Support/Allocator.h" +#include "gtest/gtest.h" + +namespace { + +using llvm::abi::ArgInfo; +using llvm::abi::Type; +using llvm::abi::TypeBuilder; + +class ArgInfoTest : public ::testing::Test { +protected: + llvm::BumpPtrAllocator Alloc; + TypeBuilder TB; + const Type *I32; + + ArgInfoTest() + : TB(Alloc), I32(TB.getIntegerType(32, llvm::Align(4), /*Signed=*/true)) { + } +}; + +TEST_F(ArgInfoTest, DirectCanBeFlattenedDefaultsTrue) { + EXPECT_TRUE(ArgInfo::getDirect().getCanBeFlattened()); + EXPECT_TRUE(ArgInfo::getDirect(I32).getCanBeFlattened()); +} + +TEST_F(ArgInfoTest, DirectCanBeFlattenedHonorsFalse) { + ArgInfo AI = ArgInfo::getDirect(I32, /*Offset=*/0, /*Align=*/std::nullopt, + /*CanBeFlattened=*/false); + EXPECT_TRUE(AI.isDirect()); + EXPECT_FALSE(AI.getCanBeFlattened()); +} + +} // namespace diff --git a/llvm/utils/gn/secondary/llvm/unittests/ABI/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/ABI/BUILD.gn index f461ac4cb98a9..4ada6c931fa67 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/ABI/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/ABI/BUILD.gn @@ -8,6 +8,7 @@ unittest("ABITests") { ] sources = [ "AArch64TargetInfoTest.cpp", + "FunctionInfoTest.cpp", "X86TargetInfoTest.cpp", ] } `````````` </details> https://github.com/llvm/llvm-project/pull/220579 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
