[clang] [CIR] Correctly pass func self-comdat & alignment (PR #223773)

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 17 13:50:09 PDT 2026


================
@@ -3379,6 +3379,29 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
   }
 
   assert(!cir::MissingFeatures::opFuncColdHotAttr());
+
+  std::optional<uint64_t> explicitAlignment;
+  if (unsigned alignment =
+          decl->getMaxAlignment() / getASTContext().getCharWidth())
+    explicitAlignment = alignment;
+  else if (langOpts.FunctionAlignment)
+    explicitAlignment = 1ull << langOpts.FunctionAlignment;
+
+  if (explicitAlignment) {
+    f.setAlignment(*explicitAlignment);
+    f.setPreferredAlignment(*explicitAlignment);
+  } else if (langOpts.PreferredFunctionAlignment) {
+    f.setPreferredAlignment(langOpts.PreferredFunctionAlignment);
+  }
+
+  // Some C++ ABIs require 2-byte alignment for member functions, in order to
+  // reserve a bit for differentiating between virtual and non-virtual member
+  // functions. If the current target's C++ ABI requires this and this is a
+  // member function, set its alignment accordingly.
+  if (getTarget().getCXXABI().areMemberFunctionsAligned()) {
+    if (isa<CXXMethodDecl>(decl) && f.getAlignment().value_or(1) < 2)
----------------
bcardosolopes wrote:

Classic guards this with `F->getPointerAlignment(getDataLayout()) < 2`, not the function's own alignment. The difference is the data layout's function-pointer alignment (`Fn`/`Fi` in the DL string): where a target already guarantees 2, classic leaves the function alone and we'd stamp an explicit `align 2` on it.

x86-64 has no `Fn` entry so the two agree there, which is why the tests won't show it. Since the point of the patch is matching classic, may use the same query?

https://github.com/llvm/llvm-project/pull/223773


More information about the cfe-commits mailing list