[flang-commits] [flang] 428b9be - [mlir] Align num elements type to LLVM ArrayType (#93230)
via flang-commits
flang-commits at lists.llvm.org
Wed May 29 13:05:48 PDT 2024
Author: Valentin Clement (バレンタイン クレメン)
Date: 2024-05-29T13:05:44-07:00
New Revision: 428b9be6484404183f51de08d2503570bade2287
URL: https://github.com/llvm/llvm-project/commit/428b9be6484404183f51de08d2503570bade2287
DIFF: https://github.com/llvm/llvm-project/commit/428b9be6484404183f51de08d2503570bade2287.diff
LOG: [mlir] Align num elements type to LLVM ArrayType (#93230)
MLIR LLMArrayType is using `unsigned` for the number of elements while
LLVM ArrayType is using `uint64_t`
https://github.com/llvm/llvm-project/blob/4ae896fe979b7db501cabde4b6b3504478958682/llvm/include/llvm/IR/DerivedTypes.h#L377
This leads to silent truncation when we use it for globals in flang.
```
program test
integer(8), parameter :: large = 2**30
real, dimension(large) :: bigarray
common /c/ bigarray
bigarray(999) = 666
end
```
The above program would result in a segfault since the global would be
of size 0 because of the silent truncation.
```
fir.global common @c_(dense<0> : vector<4294967296xi8>) : !fir.array<4294967296xi8>
```
became
```
llvm.mlir.global common @c_(dense<0> : vector<4294967296xi8>) {addr_space = 0 : i32} : !llvm.array<0 x i8>
```
This patch updates the definition of MLIR ArrayType to take `uint64_t`
as argument of the number of elements to be compatible with LLVM.
Added:
Modified:
flang/test/Fir/convert-to-llvm.fir
mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/LLVMIR/llvmir.mlir
Removed:
################################################################################
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 70cb0443e9a64..369d4bd3029bc 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -2699,3 +2699,9 @@ func.func @coordinate_array_unknown_size_1d(%arg0: !fir.ptr<!fir.array<? x i32>>
// CHECK: %[[VAL_2:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}%[[VAL_1]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// CHECK: llvm.return
// CHECK: }
+
+// -----
+
+fir.global common @c_(dense<0> : vector<4294967296xi8>) : !fir.array<4294967296xi8>
+
+// CHECK: llvm.mlir.global common @c_(dense<0> : vector<4294967296xi8>) {addr_space = 0 : i32} : !llvm.array<4294967296 x i8>
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
index b7176aa93ff1f..8f9c2f2f8a0b4 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
@@ -40,7 +40,7 @@ def LLVMArrayType : LLVMType<"LLVMArray", "array", [
```
}];
- let parameters = (ins "Type":$elementType, "unsigned":$numElements);
+ let parameters = (ins "Type":$elementType, "uint64_t":$numElements);
let assemblyFormat = [{
`<` $numElements `x` custom<PrettyLLVMType>($elementType) `>`
}];
@@ -49,7 +49,7 @@ def LLVMArrayType : LLVMType<"LLVMArray", "array", [
let builders = [
TypeBuilderWithInferredContext<(ins "Type":$elementType,
- "unsigned":$numElements)>
+ "uint64_t":$numElements)>
];
let extraClassDeclaration = [{
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index ad1dc4a36b82b..cf3f38b710130 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -154,14 +154,14 @@ bool LLVMArrayType::isValidElementType(Type type) {
type);
}
-LLVMArrayType LLVMArrayType::get(Type elementType, unsigned numElements) {
+LLVMArrayType LLVMArrayType::get(Type elementType, uint64_t numElements) {
assert(elementType && "expected non-null subtype");
return Base::get(elementType.getContext(), elementType, numElements);
}
LLVMArrayType
LLVMArrayType::getChecked(function_ref<InFlightDiagnostic()> emitError,
- Type elementType, unsigned numElements) {
+ Type elementType, uint64_t numElements) {
assert(elementType && "expected non-null subtype");
return Base::getChecked(emitError, elementType.getContext(), elementType,
numElements);
@@ -169,7 +169,7 @@ LLVMArrayType::getChecked(function_ref<InFlightDiagnostic()> emitError,
LogicalResult
LLVMArrayType::verify(function_ref<InFlightDiagnostic()> emitError,
- Type elementType, unsigned numElements) {
+ Type elementType, uint64_t numElements) {
if (!isValidElementType(elementType))
return emitError() << "invalid array element type: " << elementType;
return success();
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 1ec0736ec08bf..176821f82434d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -632,8 +632,43 @@ llvm::Constant *mlir::LLVM::detail::getLLVMConstant(
llvm::ElementCount::get(numElements, /*Scalable=*/isScalable), child);
if (llvmType->isArrayTy()) {
auto *arrayType = llvm::ArrayType::get(elementType, numElements);
- SmallVector<llvm::Constant *, 8> constants(numElements, child);
- return llvm::ConstantArray::get(arrayType, constants);
+ if (child->isZeroValue()) {
+ return llvm::ConstantAggregateZero::get(arrayType);
+ } else {
+ if (llvm::ConstantDataSequential::isElementTypeCompatible(
+ elementType)) {
+ // TODO: Handle all compatible types. This code only handles integer.
+ if (llvm::IntegerType *iTy =
+ dyn_cast<llvm::IntegerType>(elementType)) {
+ if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
+ if (ci->getBitWidth() == 8) {
+ SmallVector<int8_t> constants(numElements, ci->getZExtValue());
+ return llvm::ConstantDataArray::get(elementType->getContext(),
+ constants);
+ }
+ if (ci->getBitWidth() == 16) {
+ SmallVector<int16_t> constants(numElements, ci->getZExtValue());
+ return llvm::ConstantDataArray::get(elementType->getContext(),
+ constants);
+ }
+ if (ci->getBitWidth() == 32) {
+ SmallVector<int32_t> constants(numElements, ci->getZExtValue());
+ return llvm::ConstantDataArray::get(elementType->getContext(),
+ constants);
+ }
+ if (ci->getBitWidth() == 64) {
+ SmallVector<int64_t> constants(numElements, ci->getZExtValue());
+ return llvm::ConstantDataArray::get(elementType->getContext(),
+ constants);
+ }
+ }
+ }
+ }
+ // std::vector is used here to accomodate large number of elements that
+ // exceed SmallVector capacity.
+ std::vector<llvm::Constant *> constants(numElements, child);
+ return llvm::ConstantArray::get(arrayType, constants);
+ }
}
}
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 97f37939551d8..41a7eec1d8dfc 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2396,3 +2396,8 @@ llvm.func @zeroinit_complex_local_aggregate() {
llvm.linker_options ["/DEFAULTLIB:", "libcmt"]
//CHECK: ![[MD1]] = !{!"/DEFAULTLIB:", !"libcmtd"}
llvm.linker_options ["/DEFAULTLIB:", "libcmtd"]
+
+// -----
+
+// CHECK: @big_ = common global [4294967296 x i8] zeroinitializer
+llvm.mlir.global common @big_(dense<0> : vector<4294967296xi8>) {addr_space = 0 : i32} : !llvm.array<4294967296 x i8>
More information about the flang-commits
mailing list