https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/220579

>From 44b325ad43ef027ad3f7c8558b59febdfbe074f5 Mon Sep 17 00:00:00 2001
From: skc7 <[email protected]>
Date: Wed, 2 Sep 2026 17:58:45 +0530
Subject: [PATCH] [ABI] Add CanBeFlattened to ArgInfo for Direct struct coerces

---
 .../Transforms/CallConvLoweringPass.cpp       | 11 +++--
 llvm/include/llvm/ABI/FunctionInfo.h          | 14 +++++-
 llvm/unittests/ABI/CMakeLists.txt             |  1 +
 llvm/unittests/ABI/FunctionInfoTest.cpp       | 43 +++++++++++++++++++
 .../gn/secondary/llvm/unittests/ABI/BUILD.gn  |  1 +
 5 files changed, 64 insertions(+), 6 deletions(-)
 create mode 100644 llvm/unittests/ABI/FunctionInfoTest.cpp

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",
   ]
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to