Index: mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp =================================================================== --- mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ 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 dangle 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::get(context), rootType); + for (unsigned i = 0; i < numElements; ++i) { + auto *element = getElement(i); + auto elementValue = processConstant(element); + if (!elementValue) + return nullptr; + auto 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; } Index: mlir/test/Target/LLVMIR/Import/constant-aggregate.ll =================================================================== --- /dev/null +++ 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 } + Index: mlir/test/Target/LLVMIR/Import/zeroinitializer.ll =================================================================== --- /dev/null +++ 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 +