[clang] [CIR] Rewrite `ConstRecordBuilder` to be based on layout (PR #206137)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 26 13:02:43 PDT 2026


================
@@ -1899,44 +1321,60 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
     const unsigned numElements = value.getArraySize();
     const unsigned numInitElts = value.getArrayInitializedElts();
 
-    mlir::Attribute filler;
+    mlir::TypedAttr filler;
     if (value.hasArrayFiller()) {
-      filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
-      if (!filler)
+      mlir::Attribute fillerTemp =
+          tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
+      if (!fillerTemp)
+        return {};
+      filler = dyn_cast<mlir::TypedAttr>(fillerTemp);
+      if (!filler) {
+        cgm.errorNYI("ConstExprEmitter::tryEmitPrivate array filler should "
+                     "always be typed");
         return {};
+      }
     }
 
-    SmallVector<mlir::TypedAttr, 16> elements;
-    if (filler && builder.isNullValue(filler))
-      elements.reserve(numInitElts + 1);
+    CIRGenBuilderTy &builder = cgm.getBuilder();
+    cir::ArrayType desiredType =
+        cast<cir::ArrayType>(cgm.convertType(destType));
+
+    llvm::SmallVector<mlir::Attribute> elts;
+    if (!filler || builder.isNullValue(filler))
+      elts.reserve(numInitElts);
     else
-      elements.reserve(numInitElts);
+      elts.reserve(numElements);
 
-    mlir::Type commonElementType;
+    // Fill in the known values.
     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) {
-        commonElementType = {};
-      }
-
-      elements.push_back(elementTyped);
+      elts.push_back(element);
     }
 
-    mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);
-    if (filler && !typedFiller)
-      cgm.errorNYI("array filler should always be typed");
+    // If we have an actual value we have to insert for the filler, do so now.
+    if (filler && !builder.isNullValue(filler))
+      elts.insert(elts.end(), numElements - elts.size(), filler);
 
-    mlir::Type desiredType = cgm.convertType(destType);
-    return emitArrayConstant(cgm, desiredType, commonElementType, numElements,
-                             elements, typedFiller);
+    // Remove all null values at the end, so they become 'trailing zeroes'.
+    while (!elts.empty() && builder.isNullValue(elts.back()))
+      elts.pop_back();
+
+    if (elts.empty())
+      return cir::ZeroAttr::get(desiredType);
+
+    if (desiredType.getSize() == 0 && elts.size() > 0) {
----------------
erichkeane wrote:

That is a good concern... They would definitely skip the NYI here but should.  Since FAM is the one place where we the zero itself is meaningful, we can't actually remove it.  I'll write a test and fix this up. 

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


More information about the cfe-commits mailing list