llvm-project/llvm/test/CodeGen/DirectX/matrix-transpose.ll
Deric C. 9210b3a099
[HLSL][DirectX] Add transpose HLSL intrinsic and DXIL lowering of llvm.matrix.transpose (#186263)
Fixes #184922

- [x] Implement `transpose` clang builtin in `Builtins.td`
- [x] Link `transpose` clang builtin with `hlsl_alias_intrinsics.h`
- [x] Add sema checks for `transpose` to `CheckHLSLBuiltinFunctionCall`
in `SemaHLSL.cpp`
- [x] Add codegen for `transpose` to `EmitHLSLBuiltinExpr` in
`CGHLSLBuiltins.cpp`
  - `transpose` lowers to the `llvm.matrix.transpose` intrinsic
- [x] Add codegen tests to
`clang/test/CodeGenHLSL/builtins/transpose.hlsl`
- [x] Add sema tests to
`clang/test/SemaHLSL/BuiltIns/transpose-errors.hlsl`
- [x] Implement lowering of the `llvm.matrix.transpose` intrinsic in the
DXIL backend in `DXILIntrinsicExpansion.cpp`
- The intrinsic lowers to a shufflevector like in DXC
https://hlsl.godbolt.org/z/Gj959q6sq
- [x] Add DXIL lowering tests to
`llvm/test/CodeGen/DirectX/matrix-transpose.ll`

Assisted-by: claude-opus-4.6
2026-03-13 15:00:27 -07:00

66 lines
3.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s
; Verify that llvm.matrix.transpose is expanded to shufflevector for DXIL.
declare <6 x float> @llvm.matrix.transpose.v6f32(<6 x float>, i32, i32)
declare <12 x i32> @llvm.matrix.transpose.v12i32(<12 x i32>, i32, i32)
declare <16 x float> @llvm.matrix.transpose.v16f32(<16 x float>, i32, i32)
declare <4 x float> @llvm.matrix.transpose.v4f32(<4 x float>, i32, i32)
declare <4 x half> @llvm.matrix.transpose.v4f16(<4 x half>, i32, i32)
; 2x3 float -> 3x2 float
define <6 x float> @test_transpose_float2x3(<6 x float> %m) {
; CHECK-LABEL: define <6 x float> @test_transpose_float2x3(
; CHECK-SAME: <6 x float> [[M:%.*]]) {
; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <6 x float> [[M]], <6 x float> poison, <6 x i32> <i32 0, i32 2, i32 4, i32 1, i32 3, i32 5>
; CHECK-NEXT: ret <6 x float> [[TMP12]]
;
%r = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> %m, i32 2, i32 3)
ret <6 x float> %r
}
; 4x3 int -> 3x4 int
define <12 x i32> @test_transpose_int4x3(<12 x i32> %m) {
; CHECK-LABEL: define <12 x i32> @test_transpose_int4x3(
; CHECK-SAME: <12 x i32> [[M:%.*]]) {
; CHECK-NEXT: [[TMP24:%.*]] = shufflevector <12 x i32> [[M]], <12 x i32> poison, <12 x i32> <i32 0, i32 4, i32 8, i32 1, i32 5, i32 9, i32 2, i32 6, i32 10, i32 3, i32 7, i32 11>
; CHECK-NEXT: ret <12 x i32> [[TMP24]]
;
%r = call <12 x i32> @llvm.matrix.transpose.v12i32(<12 x i32> %m, i32 4, i32 3)
ret <12 x i32> %r
}
; 4x4 float -> 4x4 float
define <16 x float> @test_transpose_float4x4(<16 x float> %m) {
; CHECK-LABEL: define <16 x float> @test_transpose_float4x4(
; CHECK-SAME: <16 x float> [[M:%.*]]) {
; CHECK-NEXT: [[TMP32:%.*]] = shufflevector <16 x float> [[M]], <16 x float> poison, <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 1, i32 5, i32 9, i32 13, i32 2, i32 6, i32 10, i32 14, i32 3, i32 7, i32 11, i32 15>
; CHECK-NEXT: ret <16 x float> [[TMP32]]
;
%r = call <16 x float> @llvm.matrix.transpose.v16f32(<16 x float> %m, i32 4, i32 4)
ret <16 x float> %r
}
; 1x4 float -> 4x1 float
define <4 x float> @test_transpose_float1x4(<4 x float> %m) {
; CHECK-LABEL: define <4 x float> @test_transpose_float1x4(
; CHECK-SAME: <4 x float> [[M:%.*]]) {
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <4 x float> [[M]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT: ret <4 x float> [[TMP8]]
;
%r = call <4 x float> @llvm.matrix.transpose.v4f32(<4 x float> %m, i32 1, i32 4)
ret <4 x float> %r
}
; 2x2 half -> 2x2 half
define <4 x half> @test_transpose_half2x2(<4 x half> %m) {
; CHECK-LABEL: define <4 x half> @test_transpose_half2x2(
; CHECK-SAME: <4 x half> [[M:%.*]]) {
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <4 x half> [[M]], <4 x half> poison, <4 x i32> <i32 0, i32 2, i32 1, i32 3>
; CHECK-NEXT: ret <4 x half> [[TMP8]]
;
%r = call <4 x half> @llvm.matrix.transpose.v4f16(<4 x half> %m, i32 2, i32 2)
ret <4 x half> %r
}