llvm-project/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
Steven Perron 87e8e7d8f0
[SPIRV] Implement lowering for llvm.matrix.transpose and llvm.matrix.multiply (#172050)
This patch implements the lowering for the llvm.matrix.transpose and
llvm.matrix.multiply intrinsics in the SPIR-V backend.

- llvm.matrix.transpose is lowered to a G_SHUFFLE_VECTOR with a
  mask calculated to transpose the elements.
- llvm.matrix.multiply is lowered by decomposing the operation into
  dot products of rows and columns:
  - Rows and columns are extracted using G_UNMERGE_VALUES or shuffles.
  - Dot products are computed using OpDot for floating point vectors
    or standard arithmetic for scalars/integers.
  - The result is reconstructed using G_BUILD_VECTOR.

This change also updates SPIRVPostLegalizer to improve type deduction
for G_UNMERGE_VALUES, enabling correct type assignment for the
intermediate virtual registers generated during lowering.

New tests are added to verify support for various matrix sizes and
element types (float and int).
2025-12-27 09:59:53 -05:00

62 lines
2.6 KiB
C++

//===-- SPIRVCombinerHelper.h -----------------------------------*- C++ -*-===//
//
// 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 contains common combine transformations that may be used in a combine
/// pass.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H
#define LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H
#include "SPIRVSubtarget.h"
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
namespace llvm {
class SPIRVCombinerHelper : public CombinerHelper {
protected:
const SPIRVSubtarget &STI;
public:
using CombinerHelper::CombinerHelper;
SPIRVCombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
bool IsPreLegalize, GISelValueTracking *VT,
MachineDominatorTree *MDT, const LegalizerInfo *LI,
const SPIRVSubtarget &STI);
bool matchLengthToDistance(MachineInstr &MI) const;
void applySPIRVDistance(MachineInstr &MI) const;
bool matchSelectToFaceForward(MachineInstr &MI) const;
void applySPIRVFaceForward(MachineInstr &MI) const;
bool matchMatrixTranspose(MachineInstr &MI) const;
void applyMatrixTranspose(MachineInstr &MI) const;
bool matchMatrixMultiply(MachineInstr &MI) const;
void applyMatrixMultiply(MachineInstr &MI) const;
private:
SPIRVType *getDotProductVectorType(Register ResReg, uint32_t K,
SPIRVGlobalRegistry *GR) const;
SmallVector<Register, 4> extractColumns(Register BReg, uint32_t N,
SPIRVType *SpvVecType,
SPIRVGlobalRegistry *GR) const;
SmallVector<Register, 4> extractRows(Register AReg, uint32_t NumRows,
uint32_t NumCols, SPIRVType *SpvRowType,
SPIRVGlobalRegistry *GR) const;
SmallVector<Register, 16>
computeDotProducts(const SmallVector<Register, 4> &RowsA,
const SmallVector<Register, 4> &ColsB,
SPIRVType *SpvVecType, SPIRVGlobalRegistry *GR) const;
Register computeDotProduct(Register RowA, Register ColB,
SPIRVType *SpvVecType,
SPIRVGlobalRegistry *GR) const;
};
} // end namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVCOMBINERHELPER_H