diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -498,6 +498,42 @@ return nullptr; return instMap[c] = bEntry.create(UnknownLoc::get(context), type); } + + if (isa(c) || isa(c)) { + unsigned numElements = c->getNumOperands(); + std::function getElement = + [&](unsigned index) -> llvm::Constant * { + return c->getAggregateElement(index); + }; + // llvm::ConstantAggregateZero doesn't take any operand + // so its getNumOperands is always zero. + if (auto *caz = dyn_cast(c)) { + numElements = caz->getElementCount().getFixedValue(); + // We want to capture the pointer rather than reference + // to the pointer since the latter will become dangling upon + // exiting the scope. + getElement = [=](unsigned index) -> llvm::Constant * { + return caz->getElementValue(index); + }; + } + + // Generate a llvm.undef as the root value first. + Type rootType = processType(c->getType()); + if (!rootType) + return nullptr; + Value root = bEntry.create(unknownLoc, rootType); + for (unsigned i = 0; i < numElements; ++i) { + llvm::Constant *element = getElement(i); + Value elementValue = processConstant(element); + if (!elementValue) + return nullptr; + ArrayAttr indexAttr = bEntry.getI32ArrayAttr({static_cast(i)}); + root = bEntry.create(UnknownLoc::get(context), rootType, + root, elementValue, indexAttr); + } + return root; + } + emitError(unknownLoc) << "unhandled constant: " << diag(*c); return nullptr; } diff --git a/mlir/test/Target/LLVMIR/import.ll b/mlir/test/Target/LLVMIR/Import/basic.ll rename from mlir/test/Target/LLVMIR/import.ll rename to mlir/test/Target/LLVMIR/Import/basic.ll diff --git a/mlir/test/Target/LLVMIR/Import/constant-aggregate.ll b/mlir/test/Target/LLVMIR/Import/constant-aggregate.ll new file mode 100644 --- /dev/null +++ b/mlir/test/Target/LLVMIR/Import/constant-aggregate.ll @@ -0,0 +1,32 @@ +; RUN: mlir-translate --import-llvm %s | FileCheck %s + +; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(7 : i32) : i32 +; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(8 : i16) : i16 +; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(4 : i8) : i8 +; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(9 : i32) : i32 +; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"SimpleAggType", (i32, i8, i16, i32)> +; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C3]], %[[ROOT]][0 : i32] +; CHECK: %[[CHAIN1:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN0]][1 : i32] +; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN1]][2 : i32] +; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C0]], %[[CHAIN2]][3 : i32] +; CHECK: llvm.return %[[CHAIN3]] +%SimpleAggType = type {i32, i8, i16, i32} +@simpleAgg = global %SimpleAggType {i32 9, i8 4, i16 8, i32 7} + +; CHECK: %[[NP:.+]] = llvm.mlir.null : !llvm.ptr> +; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(4 : i32) : i32 +; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(3 : i16) : i16 +; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(2 : i8) : i8 +; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(1 : i32) : i32 +; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"SimpleAggType", (i32, i8, i16, i32)> +; CHECK: %[[CHAIN0:.+]] = llvm.insertvalue %[[C3]], %[[ROOT]][0 : i32] +; CHECK: %[[CHAIN1:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN0]][1 : i32] +; CHECK: %[[CHAIN2:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN1]][2 : i32] +; CHECK: %[[CHAIN3:.+]] = llvm.insertvalue %[[C0]], %[[CHAIN2]][3 : i32] +; CHECK: %[[ROOT2:.+]] = llvm.mlir.undef : !llvm.struct<"NestedAggType", (struct<"SimpleAggType", (i32, i8, i16, i32)>, ptr>)> +; CHECK: %[[CHAIN4:.+]] = llvm.insertvalue %[[CHAIN3]], %[[ROOT2]][0 : i32] +; CHECK: %[[CHAIN5:.+]] = llvm.insertvalue %[[NP]], %[[CHAIN4]][1 : i32] +; CHECK: llvm.return %[[CHAIN5]] +%NestedAggType = type {%SimpleAggType, %SimpleAggType*} +@nestedAgg = global %NestedAggType { %SimpleAggType{i32 1, i8 2, i16 3, i32 4}, %SimpleAggType* null } + diff --git a/mlir/test/Target/LLVMIR/data-layout.ll b/mlir/test/Target/LLVMIR/Import/data-layout.ll rename from mlir/test/Target/LLVMIR/data-layout.ll rename to mlir/test/Target/LLVMIR/Import/data-layout.ll diff --git a/mlir/test/Target/LLVMIR/import-opaque.ll b/mlir/test/Target/LLVMIR/Import/opaque.ll rename from mlir/test/Target/LLVMIR/import-opaque.ll rename to mlir/test/Target/LLVMIR/Import/opaque.ll diff --git a/mlir/test/Target/LLVMIR/Import/zeroinitializer.ll b/mlir/test/Target/LLVMIR/Import/zeroinitializer.ll new file mode 100644 --- /dev/null +++ b/mlir/test/Target/LLVMIR/Import/zeroinitializer.ll @@ -0,0 +1,14 @@ +; RUN: mlir-translate --import-llvm %s | FileCheck %s + +%Domain = type { %Domain**, %Domain* } + +; CHECK: llvm.mlir.global external @D() : +; CHECK-SAME: !llvm.struct<"Domain", (ptr>>, ptr>)> +; CHECK-DAG: %[[E0:.+]] = llvm.mlir.null : !llvm.ptr>>, ptr>)>> +; CHECK-DAG: %[[E1:.+]] = llvm.mlir.null : !llvm.ptr>>, ptr>)>>> +; CHECK: %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"Domain", (ptr>>, ptr>)> +; CHECK: %[[CHAIN:.+]] = llvm.insertvalue %[[E1]], %[[ROOT]][0 : i32] +; CHECK: %[[RES:.+]] = llvm.insertvalue %[[E0]], %[[CHAIN]][1 : i32] +; CHECK: llvm.return %[[RES]] +@D = global %Domain zeroinitializer +