llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) <details> <summary>Changes</summary> If an array is explicitly initialized with more than eight non-zero values followed by a number of explicit zero initializers, CIR generates a constant record initializer with a constant array that is declared as the size of the non-zero initializers but with the explicit zero initializers included in the array initialization attribute. This resulted in an error when we tried to lower that attribute to LLVM IR. This patch fixes that problem and adds a verifier to ConstantArrayAttr to check for that condition. --- Full diff: https://github.com/llvm/llvm-project/pull/184933.diff 4 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+2-2) - (modified) clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (+4) - (modified) clang/test/CIR/CodeGen/array.cpp (+23) - (added) clang/test/CIR/IR/invalid-const-array.cir (+6) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 9d17c8937aac9..b697ca5cd3f6d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -1167,8 +1167,8 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, // (the nonzero data and the zeroinitializer). SmallVector<mlir::Attribute> eles; eles.reserve(nonzeroLength); - for (const auto &element : elements) - eles.push_back(element); + for (unsigned i = 0; i < nonzeroLength; ++i) + eles.push_back(elements[i]); auto initial = cir::ConstArrayAttr::get( cir::ArrayType::get(commonElementType, nonzeroLength), mlir::ArrayAttr::get(builder.getContext(), eles)); diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 67509f3cf452a..4cd2073bf49aa 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -501,6 +501,10 @@ ConstArrayAttr::verify(function_ref<InFlightDiagnostic()> emitError, Type type, const auto arrayTy = mlir::cast<ArrayType>(type); // Make sure both number of elements and subelement types match type. + if (arrayAttr.size() > arrayTy.getSize()) + return emitError() << "constant array has " << arrayAttr.size() + << " values but array type has size " + << arrayTy.getSize(); if (arrayTy.getSize() != arrayAttr.size() + trailingZerosNum) return emitError() << "constant array size should match type size"; return success(); diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp index 4808abbc3200d..8edcde82c4dbf 100644 --- a/clang/test/CIR/CodeGen/array.cpp +++ b/clang/test/CIR/CodeGen/array.cpp @@ -86,6 +86,29 @@ int g[16] = {1, 2, 3, 4, 5, 6, 7, 8}; // OGCG-SAME: i32 5, i32 6, i32 7, i32 8], // OGCG-SAME: [8 x i32] zeroinitializer }> +// If we have explicit trailing zeros, those should still be combined into +// a zero initializer array. +int h[16] = {1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0}; + +// CIR: cir.global external @h = #cir.const_record<{ +// CIR-SAME: #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, +// CIR-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i, +// CIR-SAME: #cir.int<5> : !s32i, #cir.int<6> : !s32i, +// CIR-SAME: #cir.int<7> : !s32i, #cir.int<8> : !s32i]> +// CIR-SAME: : !cir.array<!s32i x 8>, +// CIR-SAME: #cir.zero : !cir.array<!s32i x 8>}> : !rec_anon_struct1 + +// LLVM: @h = global <{ [8 x i32], [8 x i32] }> +// LLVM-SAME: <{ [8 x i32] +// LLVM-SAME: [i32 1, i32 2, i32 3, i32 4, +// LLVM-SAME: i32 5, i32 6, i32 7, i32 8], +// LLVM-SAME: [8 x i32] zeroinitializer }> + +// OGCG: @h = global <{ [8 x i32], [8 x i32] }> +// OGCG-SAME: <{ [8 x i32] +// OGCG-SAME: [i32 1, i32 2, i32 3, i32 4, +// OGCG-SAME: i32 5, i32 6, i32 7, i32 8], +// OGCG-SAME: [8 x i32] zeroinitializer }> extern int b[10]; // CIR: cir.global "private" external @b : !cir.array<!s32i x 10> diff --git a/clang/test/CIR/IR/invalid-const-array.cir b/clang/test/CIR/IR/invalid-const-array.cir new file mode 100644 index 0000000000000..e2de226e5533e --- /dev/null +++ b/clang/test/CIR/IR/invalid-const-array.cir @@ -0,0 +1,6 @@ +// RUN: cir-opt %s -verify-diagnostics + +!s32i = !cir.int<s, 32> + +// expected-error @below {{constant array has 4 values but array type has size 2}} +cir.global external @a = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.array<!s32i x 2> `````````` </details> https://github.com/llvm/llvm-project/pull/184933 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
