This patch adds support for lowering vector.outerproduct to the ArmSME
MOPA intrinsic for the following types:
vector<[8]xf16>, vector<[8]xf16> -> vector<[8]x[8]xf16>
vector<[8]xbf16>, vector<[8]xbf16> -> vector<[8]x[8]xbf16>
vector<[4]xf32>, vector<[4]xf32> -> vector<[4]x[4]xf32>
vector<[2]xf64>, vector<[2]xf64> -> vector<[2]x[2]xf64>
The FP variants are lowered to FMOPA (non-widening) [1] and BFloat to
BFMOPA
(non-widening) [2].
Note at the ISA level these variants are implemented by different
architecture features, these are listed below:
FMOPA (non-widening)
* half-precision - +sme2p1,+sme-f16f16
* single-precision - +sme
* double-precision - +sme-f64f64
BFMOPA (non-widening)
* half-precision - +sme2p1,+b16b16
There's currently no way to target different features when lowering to
ArmSME. Integration tests are added for F32 and F64. We use QEMU to run
the integration tests but SME2 support isn't available yet, it's
targeted for 9.0, so integration tests for these variants excluded.
Masking is currently unsupported.
Depends on #65450.
[1] https://developer.arm.com/documentation/ddi0602/2023-06/SME-Instructions/FMOPA--non-widening---Floating-point-outer-product-and-accumulate-
[2] https://developer.arm.com/documentation/ddi0602/2023-06/SME-Instructions/BFMOPA--non-widening---BFloat16-floating-point-outer-product-and-accumulate-
45 lines
1.5 KiB
C++
45 lines
1.5 KiB
C++
//===- Utils.cpp - Utilities to support the ArmSME dialect ----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements utilities for the ArmSME dialect.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Dialect/ArmSME/Utils/Utils.h"
|
|
|
|
#include "mlir/Dialect/ArmSME/IR/ArmSME.h"
|
|
|
|
using namespace mlir;
|
|
using namespace mlir::arm_sme;
|
|
|
|
unsigned mlir::arm_sme::getSMETileSliceMinNumElts(Type type) {
|
|
assert(isValidSMETileElementType(type) && "invalid tile type!");
|
|
return MinStreamingVectorLengthInBits / type.getIntOrFloatBitWidth();
|
|
}
|
|
|
|
bool mlir::arm_sme::isValidSMETileElementType(Type type) {
|
|
return type.isInteger(8) || type.isInteger(16) || type.isInteger(32) ||
|
|
type.isInteger(64) || type.isInteger(128) || type.isF16() ||
|
|
type.isBF16() || type.isF32() || type.isF64() || type.isF128();
|
|
}
|
|
|
|
bool mlir::arm_sme::isValidSMETileVectorType(VectorType vType) {
|
|
if ((vType.getRank() != 2) || !vType.allDimsScalable())
|
|
return false;
|
|
|
|
auto elemType = vType.getElementType();
|
|
if (!isValidSMETileElementType(elemType))
|
|
return false;
|
|
|
|
unsigned minNumElts = arm_sme::getSMETileSliceMinNumElts(elemType);
|
|
if (vType.getShape() != ArrayRef<int64_t>({minNumElts, minNumElts}))
|
|
return false;
|
|
|
|
return true;
|
|
}
|