[Mlir-commits] [mlir] [mlir][LLVM] handle ArrayAttr for constant array of structs (PR #139724)
Tobias Gysi
llvmlistbot at llvm.org
Wed May 14 13:29:33 PDT 2025
================
@@ -3142,6 +3142,72 @@ static bool hasScalableVectorType(Type t) {
return false;
}
+/// Verified helper for array of struct constants.
+static LogicalResult verifyStructArrayConstant(LLVM::ConstantOp op,
+ LLVM::LLVMArrayType arrayType,
+ ArrayAttr arrayAttr, int dim) {
+ if (arrayType.getNumElements() != arrayAttr.size())
+ return op.emitOpError()
+ << "array attribute size does not match array type size in "
+ "dimension "
+ << dim << ": " << arrayAttr.size() << " vs. "
+ << arrayType.getNumElements();
+
+ llvm::DenseSet<Attribute> elementsVerified;
+
+ // Recursively verify sub-dimensions for multidimensional arrays.
+ if (auto subArrayType =
+ dyn_cast<LLVM::LLVMArrayType>(arrayType.getElementType())) {
+ for (auto [idx, elementAttr] : llvm::enumerate(arrayAttr))
+ if (elementsVerified.insert(elementAttr).second) {
+ if (isa<LLVM::ZeroAttr, LLVM::UndefAttr>(elementAttr))
+ continue;
+ auto subArrayAttr = dyn_cast<ArrayAttr>(elementAttr);
+ if (!subArrayAttr)
+ return op.emitOpError()
+ << "nested attribute for sub-array in dimension " << dim
+ << " at index " << idx
+ << " must be a zero, or undef, or array attribute";
+ if (failed(verifyStructArrayConstant(op, subArrayType, subArrayAttr,
+ dim + 1)))
+ return failure();
+ }
+ return success();
+ }
+
+ // Forbid usages of ArrayAttr for simple array types that should use
+ // DenseElementsAttr instead. Note that there would be a use case for such
+ // array types when one element value is obtained via a ptr-to-int conversion
+ // from a symbol and cannot be represented in a DenseElementsAttr, but no MLIR
+ // user needs this so far, and it seems better to avoid people misusing the
+ // ArrayAttr for simple types.
+ auto structType = dyn_cast<LLVM::LLVMStructType>(arrayType.getElementType());
+ if (!structType)
+ return op.emitOpError() << "for array with an array attribute must have a "
+ "struct element type";
+
+ // Shallow verification that leaf attributes are appropriate as struct initial
+ // value.
+ size_t numStructElements = structType.getBody().size();
+ for (auto [idx, elementAttr] : llvm::enumerate(arrayAttr))
+ if (elementsVerified.insert(elementAttr).second) {
+ if (isa<LLVM::ZeroAttr, LLVM::UndefAttr>(elementAttr))
+ continue;
+ auto subArrayAttr = dyn_cast<ArrayAttr>(elementAttr);
+ if (!subArrayAttr)
+ return op.emitOpError()
+ << "nested attribute for struct element at index " << idx
+ << " must be a zero, or undef, or array attribute";
+ if (subArrayAttr.size() != numStructElements)
+ return op.emitOpError()
+ << "nested array attribute size for struct element at index "
+ << idx << " must match struct size: " << subArrayAttr.size()
+ << " vs. " << numStructElements;
+ }
----------------
gysit wrote:
```suggestion
for (auto [idx, elementAttr] : llvm::enumerate(arrayAttr)) {
if (elementsVerified.insert(elementAttr).second) {
if (isa<LLVM::ZeroAttr, LLVM::UndefAttr>(elementAttr))
continue;
auto subArrayAttr = dyn_cast<ArrayAttr>(elementAttr);
if (!subArrayAttr)
return op.emitOpError()
<< "nested attribute for struct element at index " << idx
<< " must be a zero, or undef, or array attribute";
if (subArrayAttr.size() != numStructElements)
return op.emitOpError()
<< "nested array attribute size for struct element at index "
<< idx << " must match struct size: " << subArrayAttr.size()
<< " vs. " << numStructElements;
}
}
```
ultra nit: missing braces
https://github.com/llvm/llvm-project/pull/139724
More information about the Mlir-commits
mailing list