[mlir] Fix translation of splat constants to LLVM IR

Summary:
When converting splat constants for nested sequential LLVM IR types wrapped in
MLIR, the constant conversion was erroneously assuming it was always possible
to recursively construct a constant of a sequential type given only one value.
Instead, wait until all sequential types are unpacked recursively before
constructing a scalar constant and wrapping it into the surrounding sequential
type.

Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72688
This commit is contained in:
Alex Zinenko 2020-01-14 11:30:25 +01:00
parent 3d6c492d7a
commit d6ea8ff0d7
2 changed files with 36 additions and 1 deletions

View File

@ -49,7 +49,14 @@ llvm::Constant *ModuleTranslation::getLLVMConstant(llvm::Type *llvmType,
auto *sequentialType = cast<llvm::SequentialType>(llvmType);
auto elementType = sequentialType->getElementType();
uint64_t numElements = sequentialType->getNumElements();
auto *child = getLLVMConstant(elementType, splatAttr.getSplatValue(), loc);
// Splat value is a scalar. Extract it only if the element type is not
// another sequence type. The recursion terminates because each step removes
// one outer sequential type.
llvm::Constant *child = getLLVMConstant(
elementType,
isa<llvm::SequentialType>(elementType) ? splatAttr
: splatAttr.getSplatValue(),
loc);
if (llvmType->isVectorTy())
return llvm::ConstantVector::getSplat(numElements, child);
if (llvmType->isArrayTy()) {

View File

@ -804,6 +804,34 @@ llvm.func @vector_ops(%arg0: !llvm<"<4 x float>">, %arg1: !llvm<"<4 x i1>">, %ar
llvm.return %1 : !llvm<"<4 x float>">
}
// CHECK-LABEL: @vector_splat_1d
llvm.func @vector_splat_1d() -> !llvm<"<4 x float>"> {
// CHECK: ret <4 x float> zeroinitializer
%0 = llvm.mlir.constant(dense<0.000000e+00> : vector<4xf32>) : !llvm<"<4 x float>">
llvm.return %0 : !llvm<"<4 x float>">
}
// CHECK-LABEL: @vector_splat_2d
llvm.func @vector_splat_2d() -> !llvm<"[4 x <16 x float>]"> {
// CHECK: ret [4 x <16 x float>] zeroinitializer
%0 = llvm.mlir.constant(dense<0.000000e+00> : vector<4x16xf32>) : !llvm<"[4 x <16 x float>]">
llvm.return %0 : !llvm<"[4 x <16 x float>]">
}
// CHECK-LABEL: @vector_splat_3d
llvm.func @vector_splat_3d() -> !llvm<"[4 x [16 x <4 x float>]]"> {
// CHECK: ret [4 x [16 x <4 x float>]] zeroinitializer
%0 = llvm.mlir.constant(dense<0.000000e+00> : vector<4x16x4xf32>) : !llvm<"[4 x [16 x <4 x float>]]">
llvm.return %0 : !llvm<"[4 x [16 x <4 x float>]]">
}
// CHECK-LABEL: @vector_splat_nonzero
llvm.func @vector_splat_nonzero() -> !llvm<"<4 x float>"> {
// CHECK: ret <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
%0 = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : !llvm<"<4 x float>">
llvm.return %0 : !llvm<"<4 x float>">
}
// CHECK-LABEL: @ops
llvm.func @ops(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.i32, %arg3: !llvm.i32) -> !llvm<"{ float, i32 }"> {
// CHECK-NEXT: fsub float %0, %1