Skip to content

Conversation

@andykaylor
Copy link
Contributor

@andykaylor andykaylor commented Dec 13, 2025

This moves the code that handles CXXABI-specific lowering in ConvertCIRToLLVMPass into a standlone CIR-to-CIR transform pass. The handling of these operations was already performing a CIR-to-CIR transformation, with the CIR operations being further lowered to the LLVM dialect. This change makes that transformation a separate pass.

The LowerModule object in ConvertCIRToLLVMPass will be unused after this change, but removal of that object is being deferred to a follow-up PR to keep this change isolated to a single purpose.


Co-authored-by: Sirui Mu [email protected]

This moves the code that handles CXXABI-specific lowering in
ConvertCIRToLLVMPass into a standlone CIR-to-CIR transform pass. The
handling of these operations was already performing a CIR-to-CIR
transformation, with the CIR operations being further lowered to the LLVM
dialect. This change makes that transformation a separate pass.

The LowerModule object in ConvertCIRToLLVMPass will be unused after this
change, but removal of that object is being deferred to a follow-up PR
to keep this change isolated to a single purpose.

---------

Co-authored-by: Sirui Mu <[email protected]>
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Dec 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 13, 2025

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

This moves the code that handles CXXABI-specific lowering in ConvertCIRToLLVMPass into a standlone CIR-to-CIR transform pass. The handling of these operations was already performing a CIR-to-CIR transformation, with the CIR operations being further lowered to the LLVM dialect. This change makes that transformation a separate pass.

The LowerModule object in ConvertCIRToLLVMPass will be unused after this change, but removal of that object is being deferred to a follow-up PR to keep this change isolated to a single purpose.



Patch is 40.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172133.diff

8 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+2)
  • (modified) clang/include/clang/CIR/Dialect/Passes.h (+1)
  • (modified) clang/include/clang/CIR/Dialect/Passes.td (+11)
  • (modified) clang/lib/CIR/Dialect/Transforms/CMakeLists.txt (+1)
  • (added) clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp (+346)
  • (modified) clang/lib/CIR/Lowering/CIRPasses.cpp (+1)
  • (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+11-46)
  • (modified) clang/test/CIR/CodeGen/pointer-to-data-member.cpp (+136-63)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4922f83df0efb..ddb5bfc5a23cd 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3614,6 +3614,8 @@ def CIR_GetRuntimeMemberOp : CIR_Op<"get_runtime_member"> {
   }];
 
   let hasVerifier = 1;
+
+  let hasLLVMLowering = false;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h
index 32c3e27d07dfb..98eaf884347ed 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -23,6 +23,7 @@ namespace mlir {
 std::unique_ptr<Pass> createCIRCanonicalizePass();
 std::unique_ptr<Pass> createCIRFlattenCFGPass();
 std::unique_ptr<Pass> createCIRSimplifyPass();
+std::unique_ptr<Pass> createCXXABILoweringPass();
 std::unique_ptr<Pass> createHoistAllocasPass();
 std::unique_ptr<Pass> createLoweringPreparePass();
 std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx);
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index 0f5783945f8ae..55007adf6ffb3 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -82,6 +82,17 @@ def GotoSolver : Pass<"cir-goto-solver"> {
   let dependentDialects = ["cir::CIRDialect"];
 }
 
+def CXXABILowering : Pass<"cir-cxxabi-lowering"> {
+  let summary = "Lower abstract C++ operations to target-specific ABI form";
+  let description = [{
+    This pass lowers high-level operations that represent C++ constructs in a
+    target-independent way to concrete, target specific operations.
+  }];
+  let constructor = "mlir::createCXXABILoweringPass()";
+  let dependentDialects = ["cir::CIRDialect"];
+}
+
+
 def LoweringPrepare : Pass<"cir-lowering-prepare"> {
   let summary = "Lower to more fine-grained CIR operations before lowering to "
     "other dialects";
diff --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
index e3b7106c1d6b9..2a0d791edd22c 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -3,6 +3,7 @@ add_subdirectory(TargetLowering)
 add_clang_library(MLIRCIRTransforms
   CIRCanonicalize.cpp
   CIRSimplify.cpp
+  CXXABILowering.cpp
   FlattenCFG.cpp
   HoistAllocas.cpp
   LoweringPrepare.cpp
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
new file mode 100644
index 0000000000000..c81e69ff334da
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -0,0 +1,346 @@
+//==- CXXABILowering.cpp - lower C++ operations to target-specific ABI form -=//
+//
+// 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 "PassDetail.h"
+#include "TargetLowering/LowerModule.h"
+
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include "clang/CIR/Dialect/Passes.h"
+#include "clang/CIR/MissingFeatures.h"
+
+using namespace mlir;
+using namespace cir;
+
+namespace mlir {
+#define GEN_PASS_DEF_CXXABILOWERING
+#include "clang/CIR/Dialect/Passes.h.inc"
+} // namespace mlir
+
+namespace {
+
+template <typename Op>
+class CIROpCXXABILoweringPattern : public mlir::OpConversionPattern<Op> {
+protected:
+  mlir::DataLayout *dataLayout;
+  cir::LowerModule *lowerModule;
+
+public:
+  CIROpCXXABILoweringPattern(mlir::MLIRContext *context,
+                             const mlir::TypeConverter &typeConverter,
+                             mlir::DataLayout &dataLayout,
+                             cir::LowerModule &lowerModule)
+      : mlir::OpConversionPattern<Op>(typeConverter, context),
+        dataLayout(&dataLayout), lowerModule(&lowerModule) {}
+};
+
+#define CIR_CXXABI_LOWERING_PATTERN(name, operation)                           \
+  struct name : CIROpCXXABILoweringPattern<operation> {                        \
+    using CIROpCXXABILoweringPattern<operation>::CIROpCXXABILoweringPattern;   \
+                                                                               \
+    mlir::LogicalResult                                                        \
+    matchAndRewrite(operation op, OpAdaptor adaptor,                           \
+                    mlir::ConversionPatternRewriter &rewriter) const override; \
+  }
+
+CIR_CXXABI_LOWERING_PATTERN(CIRAllocaOpABILowering, cir::AllocaOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRConstantOpABILowering, cir::ConstantOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRFuncOpABILowering, cir::FuncOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRGetRuntimeMemberOpABILowering,
+                            cir::GetRuntimeMemberOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRGlobalOpABILowering, cir::GlobalOp);
+#undef CIR_CXXABI_LOWERING_PATTERN
+
+struct CXXABILoweringPass
+    : public impl::CXXABILoweringBase<CXXABILoweringPass> {
+  CXXABILoweringPass() = default;
+  void runOnOperation() override;
+};
+
+/// A generic ABI lowering rewrite pattern. This conversion pattern matches any
+/// CIR dialect operations with at least one operand or result of an
+/// ABI-dependent type. This conversion pattern rewrites the matched operation
+/// by replacing all its ABI-dependent operands and results with their
+/// lowered counterparts.
+class CIRGenericCXXABILoweringPattern : public mlir::ConversionPattern {
+public:
+  CIRGenericCXXABILoweringPattern(mlir::MLIRContext *context,
+                                  const mlir::TypeConverter &typeConverter)
+      : mlir::ConversionPattern(typeConverter, MatchAnyOpTypeTag(),
+                                /*benefit=*/1, context) {}
+
+  mlir::LogicalResult
+  matchAndRewrite(mlir::Operation *op, llvm::ArrayRef<mlir::Value> operands,
+                  mlir::ConversionPatternRewriter &rewriter) const override {
+    // Do not match on operations that have dedicated ABI lowering rewrite rules
+    if (llvm::isa<cir::AllocaOp, cir::ConstantOp, cir::FuncOp,
+                  cir::GetRuntimeMemberOp, cir::GlobalOp>(op))
+      return mlir::failure();
+
+    const mlir::TypeConverter *typeConverter = getTypeConverter();
+    assert(typeConverter &&
+           "CIRGenericCXXABILoweringPattern requires a type converter");
+    if (typeConverter->isLegal(op)) {
+      // The operation does not have any CXXABI-dependent operands or results,
+      // the match fails.
+      return mlir::failure();
+    }
+
+    assert(op->getNumRegions() == 0 && "CIRGenericCXXABILoweringPattern cannot "
+                                       "deal with operations with regions");
+
+    mlir::OperationState loweredOpState(op->getLoc(), op->getName());
+    loweredOpState.addOperands(operands);
+    loweredOpState.addAttributes(op->getAttrs());
+    loweredOpState.addSuccessors(op->getSuccessors());
+
+    // Lower all result types
+    llvm::SmallVector<mlir::Type> loweredResultTypes;
+    loweredResultTypes.reserve(op->getNumResults());
+    for (mlir::Type result : op->getResultTypes())
+      loweredResultTypes.push_back(typeConverter->convertType(result));
+    loweredOpState.addTypes(loweredResultTypes);
+
+    // Clone the operation with lowered operand types and result types
+    mlir::Operation *loweredOp = rewriter.create(loweredOpState);
+
+    rewriter.replaceOp(op, loweredOp);
+    return mlir::success();
+  }
+};
+
+} // namespace
+
+mlir::LogicalResult CIRAllocaOpABILowering::matchAndRewrite(
+    cir::AllocaOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type allocaPtrTy = op.getType();
+  mlir::Type allocaTy = op.getAllocaType();
+  mlir::Type loweredAllocaPtrTy = getTypeConverter()->convertType(allocaPtrTy);
+  mlir::Type loweredAllocaTy = getTypeConverter()->convertType(allocaTy);
+
+  cir::AllocaOp loweredOp = cir::AllocaOp::create(
+      rewriter, op.getLoc(), loweredAllocaPtrTy, loweredAllocaTy, op.getName(),
+      op.getAlignmentAttr(), /*dynAllocSize=*/adaptor.getDynAllocSize());
+  loweredOp.setInit(op.getInit());
+  loweredOp.setConstant(op.getConstant());
+  loweredOp.setAnnotationsAttr(op.getAnnotationsAttr());
+
+  rewriter.replaceOp(op, loweredOp);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRConstantOpABILowering::matchAndRewrite(
+    cir::ConstantOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+
+  if (mlir::isa<cir::DataMemberType>(op.getType())) {
+    auto dataMember = mlir::cast<cir::DataMemberAttr>(op.getValue());
+    mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+    mlir::TypedAttr abiValue = lowerModule->getCXXABI().lowerDataMemberConstant(
+        dataMember, layout, *getTypeConverter());
+    rewriter.replaceOpWithNewOp<ConstantOp>(op, abiValue);
+    return mlir::success();
+  }
+
+  llvm_unreachable("constant operand is not an CXXABI-dependent type");
+}
+
+mlir::LogicalResult CIRFuncOpABILowering::matchAndRewrite(
+    cir::FuncOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  cir::FuncType opFuncType = op.getFunctionType();
+  mlir::TypeConverter::SignatureConversion signatureConversion(
+      opFuncType.getNumInputs());
+
+  for (const auto &[i, argType] : llvm::enumerate(opFuncType.getInputs())) {
+    mlir::Type loweredArgType = getTypeConverter()->convertType(argType);
+    if (!loweredArgType)
+      return mlir::failure();
+    signatureConversion.addInputs(i, loweredArgType);
+  }
+
+  mlir::Type loweredResultType =
+      getTypeConverter()->convertType(opFuncType.getReturnType());
+  if (!loweredResultType)
+    return mlir::failure();
+
+  auto loweredFuncType =
+      cir::FuncType::get(signatureConversion.getConvertedTypes(),
+                         loweredResultType, /*isVarArg=*/opFuncType.isVarArg());
+
+  // Create a new cir.func operation for the CXXABI-lowered function.
+  cir::FuncOp loweredFuncOp = rewriter.cloneWithoutRegions(op);
+  loweredFuncOp.setFunctionType(loweredFuncType);
+  rewriter.inlineRegionBefore(op.getBody(), loweredFuncOp.getBody(),
+                              loweredFuncOp.end());
+  if (mlir::failed(rewriter.convertRegionTypes(
+          &loweredFuncOp.getBody(), *getTypeConverter(), &signatureConversion)))
+    return mlir::failure();
+
+  rewriter.eraseOp(op);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRGlobalOpABILowering::matchAndRewrite(
+    cir::GlobalOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type ty = op.getSymType();
+  mlir::Type loweredTy = getTypeConverter()->convertType(ty);
+  if (!loweredTy)
+    return mlir::failure();
+
+  mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+
+  mlir::Attribute loweredInit;
+  if (mlir::isa<cir::DataMemberType>(ty)) {
+    cir::DataMemberAttr init =
+        mlir::cast_if_present<cir::DataMemberAttr>(op.getInitialValueAttr());
+    loweredInit = lowerModule->getCXXABI().lowerDataMemberConstant(
+        init, layout, *getTypeConverter());
+  } else {
+    llvm_unreachable(
+        "inputs to cir.global in ABI lowering must be data member or method");
+  }
+
+  auto newOp = mlir::cast<cir::GlobalOp>(rewriter.clone(*op.getOperation()));
+  newOp.setInitialValueAttr(loweredInit);
+  newOp.setSymType(loweredTy);
+  rewriter.replaceOp(op, newOp);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRGetRuntimeMemberOpABILowering::matchAndRewrite(
+    cir::GetRuntimeMemberOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type resTy = getTypeConverter()->convertType(op.getType());
+  mlir::Operation *newOp = lowerModule->getCXXABI().lowerGetRuntimeMember(
+      op, resTy, adaptor.getAddr(), adaptor.getMember(), rewriter);
+  rewriter.replaceOp(op, newOp);
+  return mlir::success();
+}
+
+// Prepare the type converter for the CXXABI lowering pass.
+// Even though this is a CIR-to-CIR pass, we are eliminating some CIR types.
+static void prepareCXXABITypeConverter(mlir::TypeConverter &converter,
+                                       mlir::DataLayout &dataLayout,
+                                       cir::LowerModule &lowerModule) {
+  converter.addConversion([&](mlir::Type type) -> mlir::Type { return type; });
+  // This is necessary in order to convert CIR pointer types that are pointing
+  // to CIR types that we are lowering in this pass.
+  converter.addConversion([&](cir::PointerType type) -> mlir::Type {
+    mlir::Type loweredPointeeType = converter.convertType(type.getPointee());
+    if (!loweredPointeeType)
+      return {};
+    return cir::PointerType::get(type.getContext(), loweredPointeeType,
+                                 type.getAddrSpace());
+  });
+  converter.addConversion([&](cir::DataMemberType type) -> mlir::Type {
+    mlir::Type abiType =
+        lowerModule.getCXXABI().lowerDataMemberType(type, converter);
+    return converter.convertType(abiType);
+  });
+  // This is necessary in order to convert CIR function types that have argument
+  // or return types that use CIR types that we are lowering in this pass.
+  converter.addConversion([&](cir::FuncType type) -> mlir::Type {
+    llvm::SmallVector<mlir::Type> loweredInputTypes;
+    loweredInputTypes.reserve(type.getNumInputs());
+    if (mlir::failed(
+            converter.convertTypes(type.getInputs(), loweredInputTypes)))
+      return {};
+
+    mlir::Type loweredReturnType = converter.convertType(type.getReturnType());
+    if (!loweredReturnType)
+      return {};
+
+    return cir::FuncType::get(loweredInputTypes, loweredReturnType,
+                              /*isVarArg=*/type.getVarArg());
+  });
+}
+
+static void
+populateCXXABIConversionTarget(mlir::ConversionTarget &target,
+                               const mlir::TypeConverter &typeConverter) {
+  target.addLegalOp<mlir::ModuleOp>();
+
+  // The ABI lowering pass is interested in CIR operations with operands or
+  // results of CXXABI-dependent types, or CIR operations with regions whose
+  // block arguments are of CXXABI-dependent types.
+  target.addDynamicallyLegalDialect<cir::CIRDialect>(
+      [&typeConverter](mlir::Operation *op) {
+        if (!typeConverter.isLegal(op))
+          return false;
+        return std::all_of(op->getRegions().begin(), op->getRegions().end(),
+                           [&typeConverter](mlir::Region &region) {
+                             return typeConverter.isLegal(&region);
+                           });
+      });
+
+  // Some CIR ops needs special checking for legality
+  target.addDynamicallyLegalOp<cir::FuncOp>([&typeConverter](cir::FuncOp op) {
+    return typeConverter.isLegal(op.getFunctionType());
+  });
+  target.addDynamicallyLegalOp<cir::GlobalOp>(
+      [&typeConverter](cir::GlobalOp op) {
+        return typeConverter.isLegal(op.getSymType());
+      });
+}
+
+//===----------------------------------------------------------------------===//
+// The Pass
+//===----------------------------------------------------------------------===//
+
+void CXXABILoweringPass::runOnOperation() {
+  auto module = mlir::cast<mlir::ModuleOp>(getOperation());
+  mlir::MLIRContext *ctx = module.getContext();
+
+  // If the triple is not present, e.g. CIR modules parsed from text, we
+  // cannot init LowerModule properly.
+  assert(!cir::MissingFeatures::makeTripleAlwaysPresent());
+  // If no target triple is available, skip the ABI lowering pass.
+  if (!module->hasAttr(cir::CIRDialect::getTripleAttrName()))
+    return;
+
+  mlir::PatternRewriter rewriter(ctx);
+  std::unique_ptr<cir::LowerModule> lowerModule =
+      cir::createLowerModule(module, rewriter);
+
+  mlir::DataLayout dataLayout(module);
+  mlir::TypeConverter typeConverter;
+  prepareCXXABITypeConverter(typeConverter, dataLayout, *lowerModule);
+
+  mlir::RewritePatternSet patterns(ctx);
+  patterns.add<CIRGenericCXXABILoweringPattern>(patterns.getContext(),
+                                                typeConverter);
+  patterns.add<
+      // clang-format off
+      CIRAllocaOpABILowering,
+      CIRConstantOpABILowering,
+      CIRFuncOpABILowering,
+      CIRGetRuntimeMemberOpABILowering,
+      CIRGlobalOpABILowering
+      // clang-format on
+      >(patterns.getContext(), typeConverter, dataLayout, *lowerModule);
+
+  mlir::ConversionTarget target(*ctx);
+  populateCXXABIConversionTarget(target, typeConverter);
+
+  if (failed(mlir::applyPartialConversion(module, target, std::move(patterns))))
+    signalPassFailure();
+}
+
+std::unique_ptr<Pass> mlir::createCXXABILoweringPass() {
+  return std::make_unique<CXXABILoweringPass>();
+}
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index ccc838717e421..72348ff6287b4 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -31,6 +31,7 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
   if (enableCIRSimplify)
     pm.addPass(mlir::createCIRSimplifyPass());
 
+  pm.addPass(mlir::createCXXABILoweringPass());
   pm.addPass(mlir::createLoweringPreparePass(&astContext));
 
   pm.enableVerifier(enableVerifier);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c01b2c1487709..507c5596471ad 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -258,9 +258,9 @@ class CIRAttrToValue {
     return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)
         .Case<cir::IntAttr, cir::FPAttr, cir::ConstComplexAttr,
               cir::ConstArrayAttr, cir::ConstRecordAttr, cir::ConstVectorAttr,
-              cir::ConstPtrAttr, cir::DataMemberAttr, cir::GlobalViewAttr,
-              cir::TypeInfoAttr, cir::UndefAttr, cir::VTableAttr,
-              cir::ZeroAttr>([&](auto attrT) { return visitCirAttr(attrT); })
+              cir::ConstPtrAttr, cir::GlobalViewAttr, cir::TypeInfoAttr,
+              cir::UndefAttr, cir::VTableAttr, cir::ZeroAttr>(
+            [&](auto attrT) { return visitCirAttr(attrT); })
         .Default([&](auto attrT) { return mlir::Value(); });
   }
 
@@ -271,7 +271,6 @@ class CIRAttrToValue {
   mlir::Value visitCirAttr(cir::ConstArrayAttr attr);
   mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
   mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
-  mlir::Value visitCirAttr(cir::DataMemberAttr attr);
   mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
   mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
   mlir::Value visitCirAttr(cir::UndefAttr attr);
@@ -526,15 +525,6 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstVectorAttr attr) {
                                    mlirValues));
 }
 
-mlir::Value CIRAttrToValue::visitCirAttr(cir::DataMemberAttr attr) {
-  assert(lowerMod && "lower module is not available");
-  mlir::DataLayout layout(parentOp->getParentOfType<mlir::ModuleOp>());
-  mlir::TypedAttr init =
-      lowerMod->getCXXABI().lowerDataMemberConstant(attr, layout, *converter);
-  // Recursively lower the CIR attribute produced by the C++ ABI.
-  return visit(init);
-}
-
 // GlobalViewAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
   auto moduleOp = parentOp->getParentOfType<mlir::ModuleOp>();
@@ -1776,14 +1766,6 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
       return mlir::success();
     }
     attr = op.getValue();
-  } else if (mlir::isa<cir::DataMemberType>(op.getType())) {
-    assert(lowerMod && "lower module is not available");
-    auto dataMember = mlir::cast<cir::DataMemberAttr>(op.getValue());
-    mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
-    mlir::TypedAttr abiValue = lowerMod->getCXXABI().lowerDataMemberConstant(
-        dataMember,...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 13, 2025

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

Changes

This moves the code that handles CXXABI-specific lowering in ConvertCIRToLLVMPass into a standlone CIR-to-CIR transform pass. The handling of these operations was already performing a CIR-to-CIR transformation, with the CIR operations being further lowered to the LLVM dialect. This change makes that transformation a separate pass.

The LowerModule object in ConvertCIRToLLVMPass will be unused after this change, but removal of that object is being deferred to a follow-up PR to keep this change isolated to a single purpose.



Patch is 40.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172133.diff

8 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+2)
  • (modified) clang/include/clang/CIR/Dialect/Passes.h (+1)
  • (modified) clang/include/clang/CIR/Dialect/Passes.td (+11)
  • (modified) clang/lib/CIR/Dialect/Transforms/CMakeLists.txt (+1)
  • (added) clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp (+346)
  • (modified) clang/lib/CIR/Lowering/CIRPasses.cpp (+1)
  • (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+11-46)
  • (modified) clang/test/CIR/CodeGen/pointer-to-data-member.cpp (+136-63)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4922f83df0efb..ddb5bfc5a23cd 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3614,6 +3614,8 @@ def CIR_GetRuntimeMemberOp : CIR_Op<"get_runtime_member"> {
   }];
 
   let hasVerifier = 1;
+
+  let hasLLVMLowering = false;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h
index 32c3e27d07dfb..98eaf884347ed 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -23,6 +23,7 @@ namespace mlir {
 std::unique_ptr<Pass> createCIRCanonicalizePass();
 std::unique_ptr<Pass> createCIRFlattenCFGPass();
 std::unique_ptr<Pass> createCIRSimplifyPass();
+std::unique_ptr<Pass> createCXXABILoweringPass();
 std::unique_ptr<Pass> createHoistAllocasPass();
 std::unique_ptr<Pass> createLoweringPreparePass();
 std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx);
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index 0f5783945f8ae..55007adf6ffb3 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -82,6 +82,17 @@ def GotoSolver : Pass<"cir-goto-solver"> {
   let dependentDialects = ["cir::CIRDialect"];
 }
 
+def CXXABILowering : Pass<"cir-cxxabi-lowering"> {
+  let summary = "Lower abstract C++ operations to target-specific ABI form";
+  let description = [{
+    This pass lowers high-level operations that represent C++ constructs in a
+    target-independent way to concrete, target specific operations.
+  }];
+  let constructor = "mlir::createCXXABILoweringPass()";
+  let dependentDialects = ["cir::CIRDialect"];
+}
+
+
 def LoweringPrepare : Pass<"cir-lowering-prepare"> {
   let summary = "Lower to more fine-grained CIR operations before lowering to "
     "other dialects";
diff --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
index e3b7106c1d6b9..2a0d791edd22c 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -3,6 +3,7 @@ add_subdirectory(TargetLowering)
 add_clang_library(MLIRCIRTransforms
   CIRCanonicalize.cpp
   CIRSimplify.cpp
+  CXXABILowering.cpp
   FlattenCFG.cpp
   HoistAllocas.cpp
   LoweringPrepare.cpp
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
new file mode 100644
index 0000000000000..c81e69ff334da
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -0,0 +1,346 @@
+//==- CXXABILowering.cpp - lower C++ operations to target-specific ABI form -=//
+//
+// 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 "PassDetail.h"
+#include "TargetLowering/LowerModule.h"
+
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include "clang/CIR/Dialect/Passes.h"
+#include "clang/CIR/MissingFeatures.h"
+
+using namespace mlir;
+using namespace cir;
+
+namespace mlir {
+#define GEN_PASS_DEF_CXXABILOWERING
+#include "clang/CIR/Dialect/Passes.h.inc"
+} // namespace mlir
+
+namespace {
+
+template <typename Op>
+class CIROpCXXABILoweringPattern : public mlir::OpConversionPattern<Op> {
+protected:
+  mlir::DataLayout *dataLayout;
+  cir::LowerModule *lowerModule;
+
+public:
+  CIROpCXXABILoweringPattern(mlir::MLIRContext *context,
+                             const mlir::TypeConverter &typeConverter,
+                             mlir::DataLayout &dataLayout,
+                             cir::LowerModule &lowerModule)
+      : mlir::OpConversionPattern<Op>(typeConverter, context),
+        dataLayout(&dataLayout), lowerModule(&lowerModule) {}
+};
+
+#define CIR_CXXABI_LOWERING_PATTERN(name, operation)                           \
+  struct name : CIROpCXXABILoweringPattern<operation> {                        \
+    using CIROpCXXABILoweringPattern<operation>::CIROpCXXABILoweringPattern;   \
+                                                                               \
+    mlir::LogicalResult                                                        \
+    matchAndRewrite(operation op, OpAdaptor adaptor,                           \
+                    mlir::ConversionPatternRewriter &rewriter) const override; \
+  }
+
+CIR_CXXABI_LOWERING_PATTERN(CIRAllocaOpABILowering, cir::AllocaOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRConstantOpABILowering, cir::ConstantOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRFuncOpABILowering, cir::FuncOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRGetRuntimeMemberOpABILowering,
+                            cir::GetRuntimeMemberOp);
+CIR_CXXABI_LOWERING_PATTERN(CIRGlobalOpABILowering, cir::GlobalOp);
+#undef CIR_CXXABI_LOWERING_PATTERN
+
+struct CXXABILoweringPass
+    : public impl::CXXABILoweringBase<CXXABILoweringPass> {
+  CXXABILoweringPass() = default;
+  void runOnOperation() override;
+};
+
+/// A generic ABI lowering rewrite pattern. This conversion pattern matches any
+/// CIR dialect operations with at least one operand or result of an
+/// ABI-dependent type. This conversion pattern rewrites the matched operation
+/// by replacing all its ABI-dependent operands and results with their
+/// lowered counterparts.
+class CIRGenericCXXABILoweringPattern : public mlir::ConversionPattern {
+public:
+  CIRGenericCXXABILoweringPattern(mlir::MLIRContext *context,
+                                  const mlir::TypeConverter &typeConverter)
+      : mlir::ConversionPattern(typeConverter, MatchAnyOpTypeTag(),
+                                /*benefit=*/1, context) {}
+
+  mlir::LogicalResult
+  matchAndRewrite(mlir::Operation *op, llvm::ArrayRef<mlir::Value> operands,
+                  mlir::ConversionPatternRewriter &rewriter) const override {
+    // Do not match on operations that have dedicated ABI lowering rewrite rules
+    if (llvm::isa<cir::AllocaOp, cir::ConstantOp, cir::FuncOp,
+                  cir::GetRuntimeMemberOp, cir::GlobalOp>(op))
+      return mlir::failure();
+
+    const mlir::TypeConverter *typeConverter = getTypeConverter();
+    assert(typeConverter &&
+           "CIRGenericCXXABILoweringPattern requires a type converter");
+    if (typeConverter->isLegal(op)) {
+      // The operation does not have any CXXABI-dependent operands or results,
+      // the match fails.
+      return mlir::failure();
+    }
+
+    assert(op->getNumRegions() == 0 && "CIRGenericCXXABILoweringPattern cannot "
+                                       "deal with operations with regions");
+
+    mlir::OperationState loweredOpState(op->getLoc(), op->getName());
+    loweredOpState.addOperands(operands);
+    loweredOpState.addAttributes(op->getAttrs());
+    loweredOpState.addSuccessors(op->getSuccessors());
+
+    // Lower all result types
+    llvm::SmallVector<mlir::Type> loweredResultTypes;
+    loweredResultTypes.reserve(op->getNumResults());
+    for (mlir::Type result : op->getResultTypes())
+      loweredResultTypes.push_back(typeConverter->convertType(result));
+    loweredOpState.addTypes(loweredResultTypes);
+
+    // Clone the operation with lowered operand types and result types
+    mlir::Operation *loweredOp = rewriter.create(loweredOpState);
+
+    rewriter.replaceOp(op, loweredOp);
+    return mlir::success();
+  }
+};
+
+} // namespace
+
+mlir::LogicalResult CIRAllocaOpABILowering::matchAndRewrite(
+    cir::AllocaOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type allocaPtrTy = op.getType();
+  mlir::Type allocaTy = op.getAllocaType();
+  mlir::Type loweredAllocaPtrTy = getTypeConverter()->convertType(allocaPtrTy);
+  mlir::Type loweredAllocaTy = getTypeConverter()->convertType(allocaTy);
+
+  cir::AllocaOp loweredOp = cir::AllocaOp::create(
+      rewriter, op.getLoc(), loweredAllocaPtrTy, loweredAllocaTy, op.getName(),
+      op.getAlignmentAttr(), /*dynAllocSize=*/adaptor.getDynAllocSize());
+  loweredOp.setInit(op.getInit());
+  loweredOp.setConstant(op.getConstant());
+  loweredOp.setAnnotationsAttr(op.getAnnotationsAttr());
+
+  rewriter.replaceOp(op, loweredOp);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRConstantOpABILowering::matchAndRewrite(
+    cir::ConstantOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+
+  if (mlir::isa<cir::DataMemberType>(op.getType())) {
+    auto dataMember = mlir::cast<cir::DataMemberAttr>(op.getValue());
+    mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+    mlir::TypedAttr abiValue = lowerModule->getCXXABI().lowerDataMemberConstant(
+        dataMember, layout, *getTypeConverter());
+    rewriter.replaceOpWithNewOp<ConstantOp>(op, abiValue);
+    return mlir::success();
+  }
+
+  llvm_unreachable("constant operand is not an CXXABI-dependent type");
+}
+
+mlir::LogicalResult CIRFuncOpABILowering::matchAndRewrite(
+    cir::FuncOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  cir::FuncType opFuncType = op.getFunctionType();
+  mlir::TypeConverter::SignatureConversion signatureConversion(
+      opFuncType.getNumInputs());
+
+  for (const auto &[i, argType] : llvm::enumerate(opFuncType.getInputs())) {
+    mlir::Type loweredArgType = getTypeConverter()->convertType(argType);
+    if (!loweredArgType)
+      return mlir::failure();
+    signatureConversion.addInputs(i, loweredArgType);
+  }
+
+  mlir::Type loweredResultType =
+      getTypeConverter()->convertType(opFuncType.getReturnType());
+  if (!loweredResultType)
+    return mlir::failure();
+
+  auto loweredFuncType =
+      cir::FuncType::get(signatureConversion.getConvertedTypes(),
+                         loweredResultType, /*isVarArg=*/opFuncType.isVarArg());
+
+  // Create a new cir.func operation for the CXXABI-lowered function.
+  cir::FuncOp loweredFuncOp = rewriter.cloneWithoutRegions(op);
+  loweredFuncOp.setFunctionType(loweredFuncType);
+  rewriter.inlineRegionBefore(op.getBody(), loweredFuncOp.getBody(),
+                              loweredFuncOp.end());
+  if (mlir::failed(rewriter.convertRegionTypes(
+          &loweredFuncOp.getBody(), *getTypeConverter(), &signatureConversion)))
+    return mlir::failure();
+
+  rewriter.eraseOp(op);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRGlobalOpABILowering::matchAndRewrite(
+    cir::GlobalOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type ty = op.getSymType();
+  mlir::Type loweredTy = getTypeConverter()->convertType(ty);
+  if (!loweredTy)
+    return mlir::failure();
+
+  mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+
+  mlir::Attribute loweredInit;
+  if (mlir::isa<cir::DataMemberType>(ty)) {
+    cir::DataMemberAttr init =
+        mlir::cast_if_present<cir::DataMemberAttr>(op.getInitialValueAttr());
+    loweredInit = lowerModule->getCXXABI().lowerDataMemberConstant(
+        init, layout, *getTypeConverter());
+  } else {
+    llvm_unreachable(
+        "inputs to cir.global in ABI lowering must be data member or method");
+  }
+
+  auto newOp = mlir::cast<cir::GlobalOp>(rewriter.clone(*op.getOperation()));
+  newOp.setInitialValueAttr(loweredInit);
+  newOp.setSymType(loweredTy);
+  rewriter.replaceOp(op, newOp);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRGetRuntimeMemberOpABILowering::matchAndRewrite(
+    cir::GetRuntimeMemberOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type resTy = getTypeConverter()->convertType(op.getType());
+  mlir::Operation *newOp = lowerModule->getCXXABI().lowerGetRuntimeMember(
+      op, resTy, adaptor.getAddr(), adaptor.getMember(), rewriter);
+  rewriter.replaceOp(op, newOp);
+  return mlir::success();
+}
+
+// Prepare the type converter for the CXXABI lowering pass.
+// Even though this is a CIR-to-CIR pass, we are eliminating some CIR types.
+static void prepareCXXABITypeConverter(mlir::TypeConverter &converter,
+                                       mlir::DataLayout &dataLayout,
+                                       cir::LowerModule &lowerModule) {
+  converter.addConversion([&](mlir::Type type) -> mlir::Type { return type; });
+  // This is necessary in order to convert CIR pointer types that are pointing
+  // to CIR types that we are lowering in this pass.
+  converter.addConversion([&](cir::PointerType type) -> mlir::Type {
+    mlir::Type loweredPointeeType = converter.convertType(type.getPointee());
+    if (!loweredPointeeType)
+      return {};
+    return cir::PointerType::get(type.getContext(), loweredPointeeType,
+                                 type.getAddrSpace());
+  });
+  converter.addConversion([&](cir::DataMemberType type) -> mlir::Type {
+    mlir::Type abiType =
+        lowerModule.getCXXABI().lowerDataMemberType(type, converter);
+    return converter.convertType(abiType);
+  });
+  // This is necessary in order to convert CIR function types that have argument
+  // or return types that use CIR types that we are lowering in this pass.
+  converter.addConversion([&](cir::FuncType type) -> mlir::Type {
+    llvm::SmallVector<mlir::Type> loweredInputTypes;
+    loweredInputTypes.reserve(type.getNumInputs());
+    if (mlir::failed(
+            converter.convertTypes(type.getInputs(), loweredInputTypes)))
+      return {};
+
+    mlir::Type loweredReturnType = converter.convertType(type.getReturnType());
+    if (!loweredReturnType)
+      return {};
+
+    return cir::FuncType::get(loweredInputTypes, loweredReturnType,
+                              /*isVarArg=*/type.getVarArg());
+  });
+}
+
+static void
+populateCXXABIConversionTarget(mlir::ConversionTarget &target,
+                               const mlir::TypeConverter &typeConverter) {
+  target.addLegalOp<mlir::ModuleOp>();
+
+  // The ABI lowering pass is interested in CIR operations with operands or
+  // results of CXXABI-dependent types, or CIR operations with regions whose
+  // block arguments are of CXXABI-dependent types.
+  target.addDynamicallyLegalDialect<cir::CIRDialect>(
+      [&typeConverter](mlir::Operation *op) {
+        if (!typeConverter.isLegal(op))
+          return false;
+        return std::all_of(op->getRegions().begin(), op->getRegions().end(),
+                           [&typeConverter](mlir::Region &region) {
+                             return typeConverter.isLegal(&region);
+                           });
+      });
+
+  // Some CIR ops needs special checking for legality
+  target.addDynamicallyLegalOp<cir::FuncOp>([&typeConverter](cir::FuncOp op) {
+    return typeConverter.isLegal(op.getFunctionType());
+  });
+  target.addDynamicallyLegalOp<cir::GlobalOp>(
+      [&typeConverter](cir::GlobalOp op) {
+        return typeConverter.isLegal(op.getSymType());
+      });
+}
+
+//===----------------------------------------------------------------------===//
+// The Pass
+//===----------------------------------------------------------------------===//
+
+void CXXABILoweringPass::runOnOperation() {
+  auto module = mlir::cast<mlir::ModuleOp>(getOperation());
+  mlir::MLIRContext *ctx = module.getContext();
+
+  // If the triple is not present, e.g. CIR modules parsed from text, we
+  // cannot init LowerModule properly.
+  assert(!cir::MissingFeatures::makeTripleAlwaysPresent());
+  // If no target triple is available, skip the ABI lowering pass.
+  if (!module->hasAttr(cir::CIRDialect::getTripleAttrName()))
+    return;
+
+  mlir::PatternRewriter rewriter(ctx);
+  std::unique_ptr<cir::LowerModule> lowerModule =
+      cir::createLowerModule(module, rewriter);
+
+  mlir::DataLayout dataLayout(module);
+  mlir::TypeConverter typeConverter;
+  prepareCXXABITypeConverter(typeConverter, dataLayout, *lowerModule);
+
+  mlir::RewritePatternSet patterns(ctx);
+  patterns.add<CIRGenericCXXABILoweringPattern>(patterns.getContext(),
+                                                typeConverter);
+  patterns.add<
+      // clang-format off
+      CIRAllocaOpABILowering,
+      CIRConstantOpABILowering,
+      CIRFuncOpABILowering,
+      CIRGetRuntimeMemberOpABILowering,
+      CIRGlobalOpABILowering
+      // clang-format on
+      >(patterns.getContext(), typeConverter, dataLayout, *lowerModule);
+
+  mlir::ConversionTarget target(*ctx);
+  populateCXXABIConversionTarget(target, typeConverter);
+
+  if (failed(mlir::applyPartialConversion(module, target, std::move(patterns))))
+    signalPassFailure();
+}
+
+std::unique_ptr<Pass> mlir::createCXXABILoweringPass() {
+  return std::make_unique<CXXABILoweringPass>();
+}
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index ccc838717e421..72348ff6287b4 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -31,6 +31,7 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
   if (enableCIRSimplify)
     pm.addPass(mlir::createCIRSimplifyPass());
 
+  pm.addPass(mlir::createCXXABILoweringPass());
   pm.addPass(mlir::createLoweringPreparePass(&astContext));
 
   pm.enableVerifier(enableVerifier);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c01b2c1487709..507c5596471ad 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -258,9 +258,9 @@ class CIRAttrToValue {
     return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)
         .Case<cir::IntAttr, cir::FPAttr, cir::ConstComplexAttr,
               cir::ConstArrayAttr, cir::ConstRecordAttr, cir::ConstVectorAttr,
-              cir::ConstPtrAttr, cir::DataMemberAttr, cir::GlobalViewAttr,
-              cir::TypeInfoAttr, cir::UndefAttr, cir::VTableAttr,
-              cir::ZeroAttr>([&](auto attrT) { return visitCirAttr(attrT); })
+              cir::ConstPtrAttr, cir::GlobalViewAttr, cir::TypeInfoAttr,
+              cir::UndefAttr, cir::VTableAttr, cir::ZeroAttr>(
+            [&](auto attrT) { return visitCirAttr(attrT); })
         .Default([&](auto attrT) { return mlir::Value(); });
   }
 
@@ -271,7 +271,6 @@ class CIRAttrToValue {
   mlir::Value visitCirAttr(cir::ConstArrayAttr attr);
   mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
   mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
-  mlir::Value visitCirAttr(cir::DataMemberAttr attr);
   mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
   mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
   mlir::Value visitCirAttr(cir::UndefAttr attr);
@@ -526,15 +525,6 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstVectorAttr attr) {
                                    mlirValues));
 }
 
-mlir::Value CIRAttrToValue::visitCirAttr(cir::DataMemberAttr attr) {
-  assert(lowerMod && "lower module is not available");
-  mlir::DataLayout layout(parentOp->getParentOfType<mlir::ModuleOp>());
-  mlir::TypedAttr init =
-      lowerMod->getCXXABI().lowerDataMemberConstant(attr, layout, *converter);
-  // Recursively lower the CIR attribute produced by the C++ ABI.
-  return visit(init);
-}
-
 // GlobalViewAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
   auto moduleOp = parentOp->getParentOfType<mlir::ModuleOp>();
@@ -1776,14 +1766,6 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
       return mlir::success();
     }
     attr = op.getValue();
-  } else if (mlir::isa<cir::DataMemberType>(op.getType())) {
-    assert(lowerMod && "lower module is not available");
-    auto dataMember = mlir::cast<cir::DataMemberAttr>(op.getValue());
-    mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
-    mlir::TypedAttr abiValue = lowerMod->getCXXABI().lowerDataMemberConstant(
-        dataMember,...
[truncated]

@github-actions
Copy link

🐧 Linux x64 Test Results

  • 3050 tests passed
  • 7 tests skipped

All executed tests passed, but another part of the build failed. Click on a failure below to see the details.

tools/clang/lib/CIR/Lowering/DirectToLLVM/CMakeFiles/obj.clangCIRLoweringDirectToLLVM.dir/LowerToLLVM.cpp.o
FAILED: tools/clang/lib/CIR/Lowering/DirectToLLVM/CMakeFiles/obj.clangCIRLoweringDirectToLLVM.dir/LowerToLLVM.cpp.o
sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/CIR/Lowering/DirectToLLVM -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/../mlir/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/mlir/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CIR/Dialect/Transforms/TargetLowering -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/clang/lib/CIR/Lowering/DirectToLLVM/CMakeFiles/obj.clangCIRLoweringDirectToLLVM.dir/LowerToLLVM.cpp.o -MF tools/clang/lib/CIR/Lowering/DirectToLLVM/CMakeFiles/obj.clangCIRLoweringDirectToLLVM.dir/LowerToLLVM.cpp.o.d -o tools/clang/lib/CIR/Lowering/DirectToLLVM/CMakeFiles/obj.clangCIRLoweringDirectToLLVM.dir/LowerToLLVM.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp:284:21: error: private field 'lowerMod' is not used [-Werror,-Wunused-private-field]
284 |   cir::LowerModule *lowerMod;
|                     ^
1 error generated.

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants