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

Reply via email to