Files
TheRock/compiler/amd-llvm/clang/test/CodeGenHLSL/matrix-layout-attr-overrides-default.hlsl
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

224 lines
12 KiB
HLSL

// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -fmatrix-memory-layout=column-major -o - | FileCheck %s
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -fmatrix-memory-layout=row-major -o - | FileCheck %s
// Verifies that a per-decl `[[hlsl::row_major]]` / `[[hlsl::column_major]]`
// (spelled `row_major` / `column_major` in HLSL) overrides the
// `-fmatrix-memory-layout=` default at every CodeGen lowering site:
//
// * `MatrixSubscriptExpr` index computation
// * `MatrixSingleSubscriptExpr` row extraction
// * `__builtin_hlsl_mul` matrix-multiply transpose insertion
// * `__builtin_hlsl_transpose` row/col dimension swap
// * `CK_HLSLMatrixTruncation` shuffle mask
//
// The decl-level attribute should win regardless of the TU default.
// -----------------------------------------------------------------------------
// MatrixSubscriptExpr indexing: row-major attr -> Row*NumCols + Col
// -----------------------------------------------------------------------------
export float subscript_rm(int row, int col, row_major float2x3 m) {
return m[row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z12subscript_rmiiu11matrix_typeILm2ELm3EfE
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[ROW]], 3
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[COL]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]
// -----------------------------------------------------------------------------
// MatrixSubscriptExpr indexing: column-major attr -> Col*NumRows + Row
// -----------------------------------------------------------------------------
export float subscript_cm(int row, int col, column_major float2x3 m) {
return m[row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z12subscript_cmiiu11matrix_typeILm2ELm3EfE
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[COL]], 2
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[ROW]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]
// -----------------------------------------------------------------------------
// MatrixSingleSubscriptExpr (row extraction): attribute selects the per-element
// index formula even when the TU default disagrees.
// -----------------------------------------------------------------------------
// Row-major: per-column element index is Row*NumCols + Col, materialized as a
// constant-zero / constant-one / constant-two add to (Row*3).
export float3 row_extract_rm(int row, row_major float2x3 m) {
return m[row];
}
// CHECK-LABEL: define {{.*}} <3 x float> @_Z14row_extract_rmiu11matrix_typeILm2ELm3EfE
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[ROW_OFFSET0:%.*]] = mul i32 [[ROW]], 3
// CHECK: add i32 [[ROW_OFFSET0]], 0
// CHECK: [[ROW_OFFSET1:%.*]] = mul i32 [[ROW]], 3
// CHECK: add i32 [[ROW_OFFSET1]], 1
// CHECK: [[ROW_OFFSET2:%.*]] = mul i32 [[ROW]], 3
// CHECK: add i32 [[ROW_OFFSET2]], 2
// Column-major: per-column element index is Col*NumRows + Row, so we *don't*
// see the Row*NumCols multiply; instead each column folds the constant
// Col*NumRows into the GEP, leaving just an add of Row.
export float3 row_extract_cm(int row, column_major float2x3 m) {
return m[row];
}
// CHECK-LABEL: define {{.*}} <3 x float> @_Z14row_extract_cmiu11matrix_typeILm2ELm3EfE
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: add i32 0, [[ROW]]
// CHECK: add i32 2, [[ROW]]
// CHECK: add i32 4, [[ROW]]
// -----------------------------------------------------------------------------
// __builtin_hlsl_mul (vector * matrix): row-major operand triggers a transpose
// before the column-major matrix.multiply intrinsic.
// -----------------------------------------------------------------------------
export float3 vec_mat_rm(float2 v, row_major float2x3 m) { return mul(v, m); }
// CHECK-LABEL: define {{.*}} <3 x float> @_Z10vec_mat_rmDv2_fu11matrix_typeILm2ELm3EfE
// CHECK: [[T:%.*]] = call {{.*}} <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> %{{.*}}, i32 3, i32 2)
// CHECK: call {{.*}} <3 x float> @llvm.matrix.multiply.v3f32.v2f32.v6f32(<2 x float> %{{.*}}, <6 x float> [[T]], i32 1, i32 2, i32 3)
// Column-major operand: no transpose is inserted before matrix.multiply.
export float3 vec_mat_cm(float2 v, column_major float2x3 m) { return mul(v, m); }
// CHECK-LABEL: define {{.*}} <3 x float> @_Z10vec_mat_cmDv2_fu11matrix_typeILm2ELm3EfE
// CHECK-NOT: @llvm.matrix.transpose
// CHECK: call {{.*}} <3 x float> @llvm.matrix.multiply.v3f32.v2f32.v6f32(<2 x float> %{{.*}}, <6 x float> %{{.*}}, i32 1, i32 2, i32 3)
// -----------------------------------------------------------------------------
// __builtin_hlsl_mul (matrix * matrix): mixed per-decl layouts cause a
// transpose only on the row-major operand.
// -----------------------------------------------------------------------------
// LHS row-major, RHS column-major: only LHS is transposed.
export float2x2 mat_mat_rm_cm(row_major float2x3 a, column_major float3x2 b) { return mul(a, b); }
// CHECK-LABEL: define {{.*}} <4 x float> @_Z13mat_mat_rm_cm
// CHECK: [[AMat:%.*]] = load <6 x float>, ptr %a.addr, align 4
// CHECK: [[BMat:%.*]] = load <6 x float>, ptr %b.addr, align 4
// CHECK: [[T:%.*]] = call {{.*}} <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[AMat]], i32 3, i32 2)
// CHECK: call {{.*}} <4 x float> @llvm.matrix.multiply.v4f32.v6f32.v6f32(<6 x float> [[T]], <6 x float> [[BMat]], i32 2, i32 3, i32 2)
// LHS column-major, RHS row-major: only RHS is transposed.
export float2x2 mat_mat_cm_rm(column_major float2x3 a, row_major float3x2 b) { return mul(a, b); }
// CHECK-LABEL: define {{.*}} <4 x float> @_Z13mat_mat_cm_rm
// CHECK: [[AMat:%.*]] = load <6 x float>, ptr %a.addr, align 4
// CHECK: [[BMat:%.*]] = load <6 x float>, ptr %b.addr, align 4
// CHECK: [[T:%.*]] = call {{.*}} <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[BMat]], i32 2, i32 3)
// CHECK: call {{.*}} <4 x float> @llvm.matrix.multiply.v4f32.v6f32.v6f32(<6 x float> [[AMat]], <6 x float> [[T]], i32 2, i32 3, i32 2)
// -----------------------------------------------------------------------------
// __builtin_hlsl_transpose: row-major operand swaps Rows/Cols passed to the
// underlying intrinsic.
// -----------------------------------------------------------------------------
// Row-major float2x3 transposed: passes (Cols=3, Rows=2) to the intrinsic.
export float3x2 transpose_rm(row_major float2x3 m) { return transpose(m); }
// CHECK-LABEL: define {{.*}} <6 x float> @_Z12transpose_rmu11matrix_typeILm2ELm3EfE
// CHECK: call {{.*}} <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> %{{.*}}, i32 3, i32 2)
// Column-major float2x3 transposed: passes (Rows=2, Cols=3) to the intrinsic.
export float3x2 transpose_cm(column_major float2x3 m) { return transpose(m); }
// CHECK-LABEL: define {{.*}} <6 x float> @_Z12transpose_cmu11matrix_typeILm2ELm3EfE
// CHECK: call {{.*}} <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> %{{.*}}, i32 2, i32 3)
// -----------------------------------------------------------------------------
// CK_HLSLMatrixTruncation: the shuffle mask that picks elements from the
// source matrix uses the operand's per-decl layout to flatten indices.
// -----------------------------------------------------------------------------
typedef row_major float2x2 RM22;
typedef column_major float2x2 CM22;
typedef row_major float3x3 RM33;
typedef column_major float3x3 CM33;
// Row-major source 3x2 -> row-major dest 2x2: flat row-major mask is {0,1,2,3}.
export row_major float2x2 truncate_rm(row_major float3x2 m) { return (RM22)m; }
// CHECK-LABEL: define {{.*}} <4 x float> @_Z11truncate_rmu11matrix_typeILm3ELm2EfE
// CHECK: shufflevector <6 x float> %{{.*}}, <6 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
// Column-major source 3x2 -> column-major dest 2x2: flat column-major mask is {0,1,3,4}.
export column_major float2x2 truncate_cm(column_major float3x2 m) { return (CM22)m; }
// CHECK-LABEL: define {{.*}} <4 x float> @_Z11truncate_cmu11matrix_typeILm3ELm2EfE
// CHECK: shufflevector <6 x float> %{{.*}}, <6 x float> poison, <4 x i32> <i32 0, i32 1, i32 3, i32 4>
// -----------------------------------------------------------------------------
// CK_HLSLMatrixTruncation cross-layout: when source and destination carry
// different layout keywords, `IsSrcRowMajor` and `IsDstRowMajor` differ. The
// source indices flatten using the source layout while the destination
// positions flatten using the destination layout. This is independent of the
// `-fmatrix-memory-layout=` default.
// -----------------------------------------------------------------------------
// Row-major src 3x4 -> column-major dst 3x3.
// src idx (R,C) = R*4+C; dst slot (R,C) = C*3+R.
// (0,0)->mask[0]=0 (0,1)->mask[3]=1 (0,2)->mask[6]=2
// (1,0)->mask[1]=4 (1,1)->mask[4]=5 (1,2)->mask[7]=6
// (2,0)->mask[2]=8 (2,1)->mask[5]=9 (2,2)->mask[8]=10
export column_major float3x3 truncate_rm_to_cm(row_major float3x4 m) { return (CM33)m; }
// CHECK-LABEL: define {{.*}} <9 x float> @_Z17truncate_rm_to_cmu11matrix_typeILm3ELm4EfE
// CHECK: shufflevector <12 x float> %{{.*}}, <12 x float> poison, <9 x i32> <i32 0, i32 4, i32 8, i32 1, i32 5, i32 9, i32 2, i32 6, i32 10>
// Column-major src 3x4 -> row-major dst 3x3.
// src idx (R,C) = C*3+R; dst slot (R,C) = R*3+C.
// (0,0)->mask[0]=0 (0,1)->mask[1]=3 (0,2)->mask[2]=6
// (1,0)->mask[3]=1 (1,1)->mask[4]=4 (1,2)->mask[5]=7
// (2,0)->mask[6]=2 (2,1)->mask[7]=5 (2,2)->mask[8]=8
export row_major float3x3 truncate_cm_to_rm(column_major float3x4 m) { return (RM33)m; }
// CHECK-LABEL: define {{.*}} <9 x float> @_Z17truncate_cm_to_rmu11matrix_typeILm3ELm4EfE
// CHECK: shufflevector <12 x float> %{{.*}}, <12 x float> poison, <9 x i32> <i32 0, i32 3, i32 6, i32 1, i32 4, i32 7, i32 2, i32 5, i32 8>
// -----------------------------------------------------------------------------
// Array of matrix: the per-decl layout attribute propagates through
// ConstantArrayType sugar via wrapMatrixWithLayoutAttr, so indexing into an
// array element still uses the correct layout.
// -----------------------------------------------------------------------------
// Row-major array element subscript: Row*NumCols + Col
export float arr_subscript_rm(int row, int col, row_major float2x3 arr[2]) {
return arr[1][row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z16arr_subscript_rm
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[ROW]], 3
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[COL]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]
// Column-major array element subscript: Col*NumRows + Row
export float arr_subscript_cm(int row, int col, column_major float2x3 arr[2]) {
return arr[1][row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z16arr_subscript_cm
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[COL]], 2
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[ROW]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]
// -----------------------------------------------------------------------------
// Multi-dimensional array of matrix: wrapMatrixWithLayoutAttr recurses
// through nested ConstantArrayType layers.
// -----------------------------------------------------------------------------
// Row-major 2D array element subscript: Row*NumCols + Col
export float arr2d_subscript_rm(int row, int col, row_major float2x3 arr[2][3]) {
return arr[0][1][row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z18arr2d_subscript_rm
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[ROW]], 3
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[COL]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]
// Column-major 2D array element subscript: Col*NumRows + Row
export float arr2d_subscript_cm(int row, int col, column_major float2x3 arr[2][3]) {
return arr[0][1][row][col];
}
// CHECK-LABEL: define {{.*}} float @_Z18arr2d_subscript_cm
// CHECK: [[ROW:%.*]] = load i32, ptr %row.addr
// CHECK: [[COL:%.*]] = load i32, ptr %col.addr
// CHECK: [[OFFSET:%.*]] = mul i32 [[COL]], 2
// CHECK: [[IDX:%.*]] = add i32 [[OFFSET]], [[ROW]]
// CHECK: extractelement <6 x float> %{{.*}}, i32 [[IDX]]