[clang] [CIR] Upstream global initialization for ArrayType (PR #131657)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 17 11:43:08 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

This change adds global initialization for ArrayType

Issue #<!-- -->130197

---

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


13 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+42) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+34) 
- (modified) clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h (+4-2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenDecl.cpp (-1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+112-10) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+5-33) 
- (modified) clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (+109) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+9) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+71-4) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+6) 
- (modified) clang/test/CIR/CodeGen/array.cpp (+20-5) 
- (modified) clang/test/CIR/IR/array.cir (+18-6) 
- (modified) clang/test/CIR/Lowering/array.cpp (+23-6) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 7b3741de29075..3680ded4afafe 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -154,6 +154,48 @@ def FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {
   }];
 }
 
+
+//===----------------------------------------------------------------------===//
+// ConstArrayAttr
+//===----------------------------------------------------------------------===//
+
+def ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [TypedAttrInterface]> {
+  let summary = "A constant array from ArrayAttr or StringRefAttr";
+  let description = [{
+    An CIR array attribute is an array of literals of the specified attr types.
+  }];
+
+  let parameters = (ins AttributeSelfTypeParameter<"">:$type,
+                        "mlir::Attribute":$elts,
+                        "int":$trailingZerosNum);
+
+  // Define a custom builder for the type; that removes the need to pass
+  // in an MLIRContext instance, as it can be infered from the `type`.
+  let builders = [
+    AttrBuilderWithInferredContext<(ins "cir::ArrayType":$type,
+                                        "mlir::Attribute":$elts), [{
+      int zeros = 0;
+      auto typeSize = mlir::cast<cir::ArrayType>(type).getSize();
+      if (auto str = mlir::dyn_cast<mlir::StringAttr>(elts))
+        zeros = typeSize - str.size();
+      else
+        zeros = typeSize - mlir::cast<mlir::ArrayAttr>(elts).size();
+
+      return $_get(type.getContext(), type, elts, zeros);
+    }]>
+  ];
+
+  // Printing and parsing available in CIRDialect.cpp
+  let hasCustomAssemblyFormat = 1;
+
+  // Enable verifier.
+  let genVerifyDecl = 1;
+
+  let extraClassDeclaration = [{
+    bool hasTrailingZeros() const { return getTrailingZerosNum() != 0; };
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // ConstPtrAttr
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 260ee25719be1..a2a75148ee884 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -43,6 +43,40 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
     assert(!cir::MissingFeatures::unsizedTypes());
     return false;
   }
+
+  bool isNullValue(mlir::Attribute attr) const {
+    if (mlir::isa<cir::ZeroAttr>(attr))
+      return true;
+
+    if (const auto ptrVal = mlir::dyn_cast<cir::ConstPtrAttr>(attr))
+      return ptrVal.isNullValue();
+
+    if (const auto intVal = mlir::dyn_cast<cir::IntAttr>(attr))
+      return intVal.isNullValue();
+
+    if (const auto boolVal = mlir::dyn_cast<cir::BoolAttr>(attr))
+      return !boolVal.getValue();
+
+    if (auto fpAttr = mlir::dyn_cast<cir::FPAttr>(attr)) {
+      auto fpVal = fpAttr.getValue();
+      bool ignored;
+      llvm::APFloat fv(+0.0);
+      fv.convert(fpVal.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
+                 &ignored);
+      return fv.bitwiseIsEqual(fpVal);
+    }
+
+    if (const auto arrayVal = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
+      if (mlir::isa<mlir::StringAttr>(arrayVal.getElts()))
+        return false;
+      for (const auto elt : mlir::cast<mlir::ArrayAttr>(arrayVal.getElts())) {
+        if (!isNullValue(elt))
+          return false;
+      }
+      return true;
+    }
+    return false;
+  }
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
index 5b22a8e59908d..ca4e607992bbc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
+++ b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
@@ -20,7 +20,6 @@
 
 #include "CIRGenFunction.h"
 #include "CIRGenModule.h"
-#include "llvm/ADT/SmallVector.h"
 
 namespace clang::CIRGen {
 
@@ -41,6 +40,9 @@ class ConstantEmitter {
   /// block addresses or PredefinedExprs.
   ConstantEmitter(CIRGenFunction &cgf) : cgm(cgf.cgm), cgf(&cgf) {}
 
+  ConstantEmitter(CIRGenModule &cgm, CIRGenFunction *cgf = nullptr)
+      : cgm(cgm), cgf(cgf) {}
+
   ConstantEmitter(const ConstantEmitter &other) = delete;
   ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
 
@@ -66,7 +68,7 @@ class ConstantEmitter {
   mlir::Attribute emitAbstract(SourceLocation loc, const APValue &value,
                                QualType t);
 
-  mlir::Attribute tryEmitConstantExpr(const ConstantExpr *CE);
+  mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce);
 
   // These are private helper routines of the constant emitter that
   // can't actually be private because things are split out into helper
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 27ed0113a4f55..a93e8dbcb42de 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -225,7 +225,6 @@ void CIRGenFunction::emitScalarInit(const Expr *init, mlir::Location loc,
   }
   assert(!cir::MissingFeatures::emitNullabilityCheck());
   emitStoreThroughLValue(RValue::get(value), lvalue, true);
-  return;
 }
 
 void CIRGenFunction::emitExprAsInit(const Expr *init, const ValueDecl *d,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 1ea7f6212766c..d3c22f54127c5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -158,13 +158,56 @@ class ConstExprEmitter
 
 // TODO(cir): this can be shared with LLVM's codegen
 static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) {
-  if (auto at = type->getAs<AtomicType>()) {
+  if (const auto *at = type->getAs<AtomicType>()) {
     return cgm.getASTContext().getQualifiedType(at->getValueType(),
                                                 type.getQualifiers());
   }
   return type;
 }
 
+static mlir::Attribute
+emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
+                  mlir::Type commonElementType, unsigned arrayBound,
+                  SmallVectorImpl<mlir::TypedAttr> &elements,
+                  mlir::TypedAttr filter) {
+  const auto &builder = cgm.getBuilder();
+
+  unsigned nonzeroLength = arrayBound;
+  if (elements.size() < nonzeroLength && builder.isNullValue(filter))
+    nonzeroLength = elements.size();
+
+  if (nonzeroLength == elements.size()) {
+    while (nonzeroLength > 0 &&
+           builder.isNullValue(elements[nonzeroLength - 1]))
+      --nonzeroLength;
+  }
+
+  if (nonzeroLength == 0)
+    return cir::ZeroAttr::get(builder.getContext(), desiredType);
+
+  const unsigned trailingZeroes = arrayBound - nonzeroLength;
+  if (trailingZeroes >= 8) {
+    if (elements.size() < nonzeroLength)
+      cgm.errorNYI("missing initializer for non-zero element");
+  } else if (elements.size() != arrayBound) {
+    elements.resize(arrayBound, filter);
+
+    if (filter.getType() != commonElementType)
+      cgm.errorNYI(
+          "array filter type should always be the same as element type");
+  }
+
+  SmallVector<mlir::Attribute, 4> eles;
+  eles.reserve(elements.size());
+
+  for (const auto &element : elements)
+    eles.push_back(element);
+
+  return cir::ConstArrayAttr::get(
+      cir::ArrayType::get(builder.getContext(), commonElementType, arrayBound),
+      mlir::ArrayAttr::get(builder.getContext(), eles));
+}
+
 //===----------------------------------------------------------------------===//
 //                             ConstantEmitter
 //===----------------------------------------------------------------------===//
@@ -271,16 +314,61 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
         cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
       cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");
       return {};
-    } else {
-      mlir::Type ty = cgm.convertType(destType);
-      assert(mlir::isa<cir::CIRFPTypeInterface>(ty) &&
-             "expected floating-point type");
-      return cgm.getBuilder().getAttr<cir::FPAttr>(ty, init);
     }
+
+    mlir::Type ty = cgm.convertType(destType);
+    assert(mlir::isa<cir::CIRFPTypeInterface>(ty) &&
+           "expected floating-point type");
+    return cgm.getBuilder().getAttr<cir::FPAttr>(ty, init);
   }
   case APValue::Array: {
-    cgm.errorNYI("ConstExprEmitter::tryEmitPrivate array");
-    return {};
+    const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);
+    const QualType arrayElementTy = arrayTy->getElementType();
+    const unsigned numElements = value.getArraySize();
+    const unsigned numInitElts = value.getArrayInitializedElts();
+
+    mlir::Attribute filter;
+    if (value.hasArrayFiller()) {
+      filter =
+          tryEmitPrivate(value.getArrayFiller(), arrayTy->getElementType());
+      if (!filter)
+        return {};
+    }
+
+    SmallVector<mlir::TypedAttr, 16> elements;
+    if (filter && builder.isNullValue(filter))
+      elements.reserve(numInitElts + 1);
+    else
+      elements.reserve(numInitElts);
+
+    mlir::Type commonElementType;
+    for (unsigned i = 0; i < numInitElts; ++i) {
+      const APValue &arrayElement = value.getArrayInitializedElt(i);
+      const mlir::Attribute element =
+          tryEmitPrivateForMemory(arrayElement, arrayElementTy);
+      if (!element)
+        return {};
+
+      const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
+      if (i == 0)
+        commonElementType = elementTyped.getType();
+      else if (elementTyped.getType() != commonElementType) {
+        cgm.errorNYI("ConstExprEmitter::tryEmitPrivate Array without common "
+                     "element type");
+        return {};
+      }
+
+      elements.push_back(elementTyped);
+    }
+
+    mlir::TypedAttr typedFilter =
+        llvm::dyn_cast_or_null<mlir::TypedAttr>(filter);
+    if (filter && !typedFilter)
+      cgm.errorNYI("array filter should always be typed");
+
+    mlir::Type desiredType = cgm.convertType(destType);
+    return emitArrayConstant(cgm, desiredType, commonElementType, numElements,
+                             elements, typedFilter);
   }
   case APValue::Vector: {
     cgm.errorNYI("ConstExprEmitter::tryEmitPrivate vector");
@@ -290,9 +378,23 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
     cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer");
     return {};
   }
-  case APValue::LValue:
-    cgm.errorNYI("ConstExprEmitter::tryEmitPrivate lvalue");
+  case APValue::LValue: {
+
+    if (value.getLValueBase()) {
+      cgm.errorNYI("non-null pointer initialization");
+    } else {
+
+      mlir::Type desiredType = cgm.convertType(destType);
+      if (const cir::PointerType ptrType =
+              mlir::dyn_cast<cir::PointerType>(desiredType)) {
+        return builder.getConstPtrAttr(ptrType,
+                                       value.getLValueOffset().getQuantity());
+      } else {
+        llvm_unreachable("non-pointer variable initialized with a pointer");
+      }
+    }
     return {};
+  }
   case APValue::Struct:
   case APValue::Union:
     cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 0e3e15ca2cadc..c7620a8355b2f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CIRGenModule.h"
+#include "CIRGenConstantEmitter.h"
 #include "CIRGenFunction.h"
 
 #include "clang/AST/ASTContext.h"
@@ -127,7 +128,8 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
 
 void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
                                            bool isTentative) {
-  mlir::Type type = convertType(vd->getType());
+  const QualType astTy = vd->getType();
+  const mlir::Type type = convertType(vd->getType());
   if (clang::IdentifierInfo *identifier = vd->getIdentifier()) {
     auto varOp = builder.create<cir::GlobalOp>(getLoc(vd->getSourceRange()),
                                                identifier->getName(), type);
@@ -140,38 +142,8 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
     if (initExpr) {
       mlir::Attribute initializer;
       if (APValue *value = initDecl->evaluateValue()) {
-        switch (value->getKind()) {
-        case APValue::Int: {
-          if (mlir::isa<cir::BoolType>(type))
-            initializer =
-                builder.getCIRBoolAttr(value->getInt().getZExtValue());
-          else
-            initializer = builder.getAttr<cir::IntAttr>(type, value->getInt());
-          break;
-        }
-        case APValue::Float: {
-          initializer = builder.getAttr<cir::FPAttr>(type, value->getFloat());
-          break;
-        }
-        case APValue::LValue: {
-          if (value->getLValueBase()) {
-            errorNYI(initExpr->getSourceRange(),
-                     "non-null pointer initialization");
-          } else {
-            if (auto ptrType = mlir::dyn_cast<cir::PointerType>(type)) {
-              initializer = builder.getConstPtrAttr(
-                  ptrType, value->getLValueOffset().getQuantity());
-            } else {
-              llvm_unreachable(
-                  "non-pointer variable initialized with a pointer");
-            }
-          }
-          break;
-        }
-        default:
-          errorNYI(initExpr->getSourceRange(), "unsupported initializer kind");
-          break;
-        }
+        ConstantEmitter emitter(*this);
+        initializer = emitter.tryEmitPrivateForMemory(*value, astTy);
       } else {
         errorNYI(initExpr->getSourceRange(), "non-constant initializer");
       }
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 8e8f7d5b7d7cb..8dfe56b75a47b 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -190,6 +190,115 @@ LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// CIR ConstArrayAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+ConstArrayAttr::verify(function_ref<::mlir::InFlightDiagnostic()> emitError,
+                       Type type, Attribute elts, int trailingZerosNum) {
+
+  if (!(mlir::isa<ArrayAttr>(elts) || mlir::isa<StringAttr>(elts)))
+    return emitError() << "constant array expects ArrayAttr or StringAttr";
+
+  if (StringAttr strAttr = mlir::dyn_cast<StringAttr>(elts)) {
+    ArrayType arrayTy = mlir::cast<ArrayType>(type);
+    IntType intTy = mlir::dyn_cast<IntType>(arrayTy.getEltType());
+
+    // TODO: add CIR type for char.
+    if (!intTy || intTy.getWidth() != 8) {
+      emitError() << "constant array element for string literals expects "
+                     "!cir.int<u, 8> element type";
+      return failure();
+    }
+    return success();
+  }
+
+  assert(mlir::isa<ArrayAttr>(elts));
+  ArrayAttr arrayAttr = mlir::cast<mlir::ArrayAttr>(elts);
+  ArrayType arrayTy = mlir::cast<ArrayType>(type);
+
+  // Make sure both number of elements and subelement types match type.
+  if (arrayTy.getSize() != arrayAttr.size() + trailingZerosNum)
+    return emitError() << "constant array size should match type size";
+  return success();
+}
+
+Attribute ConstArrayAttr::parse(AsmParser &parser, Type type) {
+  ::mlir::FailureOr<Type> resultTy;
+  ::mlir::FailureOr<Attribute> resultVal;
+  ::llvm::SMLoc loc = parser.getCurrentLocation();
+  (void)loc;
+  // Parse literal '<'
+  if (parser.parseLess())
+    return {};
+
+  // Parse variable 'value'
+  resultVal = FieldParser<Attribute>::parse(parser);
+  if (failed(resultVal)) {
+    parser.emitError(
+        parser.getCurrentLocation(),
+        "failed to parse ConstArrayAttr parameter 'value' which is "
+        "to be a `Attribute`");
+    return {};
+  }
+
+  // ArrayAttrrs have per-element type, not the type of the array...
+  if (mlir::dyn_cast<ArrayAttr>(*resultVal)) {
+    // Array has implicit type: infer from const array type.
+    if (parser.parseOptionalColon().failed()) {
+      resultTy = type;
+    } else { // Array has explicit type: parse it.
+      resultTy = FieldParser<Type>::parse(parser);
+      if (failed(resultTy)) {
+        parser.emitError(
+            parser.getCurrentLocation(),
+            "failed to parse ConstArrayAttr parameter 'type' which is "
+            "to be a `::mlir::Type`");
+        return {};
+      }
+    }
+  } else {
+    assert(mlir::isa<TypedAttr>(*resultVal) && "IDK");
+    auto ta = mlir::cast<TypedAttr>(*resultVal);
+    resultTy = ta.getType();
+    if (mlir::isa<mlir::NoneType>(*resultTy)) {
+      parser.emitError(parser.getCurrentLocation(),
+                       "expected type declaration for string literal");
+      return {};
+    }
+  }
+
+  auto zeros = 0;
+  if (parser.parseOptionalComma().succeeded()) {
+    if (parser.parseOptionalKeyword("trailing_zeros").succeeded()) {
+      auto typeSize = mlir::cast<cir::ArrayType>(resultTy.value()).getSize();
+      auto elts = resultVal.value();
+      if (auto str = mlir::dyn_cast<mlir::StringAttr>(elts))
+        zeros = typeSize - str.size();
+      else
+        zeros = typeSize - mlir::cast<mlir::ArrayAttr>(elts).size();
+    } else {
+      return {};
+    }
+  }
+
+  // Parse literal '>'
+  if (parser.parseGreater())
+    return {};
+
+  return parser.getChecked<ConstArrayAttr>(
+      loc, parser.getContext(), resultTy.value(), resultVal.value(), zeros);
+}
+
+void ConstArrayAttr::print(AsmPrinter &printer) const {
+  printer << "<";
+  printer.printStrippedAttrOrType(getElts());
+  if (getTrailingZerosNum())
+    printer << ", trailing_zeros";
+  printer << ">";
+}
+
 //===----------------------------------------------------------------------===//
 // CIR Dialect
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index d041791770d82..467e6237ef01a 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -149,6 +149,12 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
     return success();
   }
 
+  if (isa<cir::ZeroAttr>(attrType)) {
+    if (::mlir::isa<cir::ArrayType>(opType))
+      return success();
+    return op->emitOpError("zero expects struct or array type");
+  }
+
   if (mlir::isa<cir::BoolAttr>(attrType)) {
     if (!mlir::isa<cir::BoolType>(opType))
       return op->emitOpError("result type (")
@@ -166,6 +172,9 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
     return success();
   }
 
+  if (mlir::isa<cir::ConstArrayAttr>(attrType))
+    return success();
+
   assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");
   return op->emitOpError("global with type ")
          << cast<TypedAttr>(attrType).getType() << " not yet supported";
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0cd27ecf1a3bd..f0b9986a9efaf 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -113,6 +113,21 @@ static mlir::Value emitToMemory(mlir::ConversionPatternRewriter &rewriter,
   return value;
 }
 
+static mlir::Value
+emitCirAttrToMemory(mlir::Operation *parentOp, mlir::Attribute attr,
+                    mlir::ConversionPatternRewriter &rewriter,
+                    const mlir::TypeConverter *converter,
+                    mlir::DataLayout const &dataLayout) {
+
+  mlir::Value loweredValue =
+      lowerCirAttrAsValue(parentOp, attr, rewriter, converter);
+  if (auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(attr)) {
+    return emitToMemory(rewriter, dataLayout, boolAttr.getType(), loweredValue);
+  }
+
+  return loweredValue;
+}
+
 mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage) {
   using CIR = cir::GlobalLinkageKind;
   using LLVM = mlir::LLVM::Linkage;
@@ -151,14 +166,1...
[truncated]

``````````

</details>


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


More information about the cfe-commits mailing list