llvm-project/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptDynamicSwizzle.hlsl
Farzon Lotfi 1bb916c9af
[HLSL] Represent Matrix as arrays of vectors in memory (#179861)
fixes https://github.com/llvm/llvm-project/issues/179859

For matrix types we need to check the language mode so we can change the
matrix memory layout to arrays of vectors. To make this play nice with
how the rest of clang treats matrices we need to modify the
MaybeConvertMatrixAddress and the CreateMemTemp function to know how to
reconstruct a flattened vector.

Rest of changes is just test updates.
2026-02-06 16:25:20 -05:00

157 lines
9.7 KiB
HLSL

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s
// CHECK-LABEL: define hidden void @_Z9setMatrixRu11matrix_typeILm4ELm4EfEiDv4_f(
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(64) [[M:%.*]], i32 noundef [[INDEX:%.*]], <4 x float> noundef nofpclass(nan inf) [[V:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x float>, align 16
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: store <4 x float> [[V]], ptr [[V_ADDR]], align 16
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[V_ADDR]], align 16
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]]
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP3:%.*]] = add i32 12, [[TMP2]]
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP0]], i32 0
// CHECK-NEXT: [[TMP5:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 [[TMP3]]
// CHECK-NEXT: store float [[TMP4]], ptr [[TMP5]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = add i32 8, [[TMP2]]
// CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[TMP0]], i32 1
// CHECK-NEXT: [[TMP8:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 [[TMP6]]
// CHECK-NEXT: store float [[TMP7]], ptr [[TMP8]], align 4
// CHECK-NEXT: [[TMP9:%.*]] = add i32 4, [[TMP2]]
// CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x float> [[TMP0]], i32 2
// CHECK-NEXT: [[TMP11:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 [[TMP9]]
// CHECK-NEXT: store float [[TMP10]], ptr [[TMP11]], align 4
// CHECK-NEXT: [[TMP12:%.*]] = add i32 0, [[TMP2]]
// CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x float> [[TMP0]], i32 3
// CHECK-NEXT: [[TMP14:%.*]] = getelementptr <16 x float>, ptr [[TMP1]], i32 0, i32 [[TMP12]]
// CHECK-NEXT: store float [[TMP13]], ptr [[TMP14]], align 4
// CHECK-NEXT: ret void
//
void setMatrix(out float4x4 M, int index, float4 V) {
M[index].abgr = V;
}
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z9getMatrixu11matrix_typeILm4ELm4EfEi(
// CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [4 x <4 x float>], align 4
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: store <16 x float> [[M]], ptr [[M_ADDR]], align 4
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
// CHECK-NEXT: [[TMP3:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP2]]
// CHECK-NEXT: [[TMP4:%.*]] = insertelement <3 x float> poison, float [[TMP3]], i32 0
// CHECK-NEXT: [[TMP5:%.*]] = add i32 4, [[TMP0]]
// CHECK-NEXT: [[TMP6:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP5]]
// CHECK-NEXT: [[TMP7:%.*]] = insertelement <3 x float> [[TMP4]], float [[TMP6]], i32 1
// CHECK-NEXT: [[TMP8:%.*]] = add i32 8, [[TMP0]]
// CHECK-NEXT: [[TMP9:%.*]] = extractelement <16 x float> [[TMP1]], i32 [[TMP8]]
// CHECK-NEXT: [[TMP10:%.*]] = insertelement <3 x float> [[TMP7]], float [[TMP9]], i32 2
// CHECK-NEXT: ret <3 x float> [[TMP10]]
//
float3 getMatrix(float4x4 M, int index) {
return M[index].rgb;
}
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z9getMatrixu11matrix_typeILm3ELm3EfEi(
// CHECK-SAME: <9 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [3 x <3 x float>], align 4
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: store <9 x float> [[M]], ptr [[M_ADDR]], align 4
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP1:%.*]] = load <9 x float>, ptr [[M_ADDR]], align 4
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
// CHECK-NEXT: [[TMP3:%.*]] = extractelement <9 x float> [[TMP1]], i32 [[TMP2]]
// CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x float> poison, float [[TMP3]], i32 0
// CHECK-NEXT: [[TMP5:%.*]] = add i32 3, [[TMP0]]
// CHECK-NEXT: [[TMP6:%.*]] = extractelement <9 x float> [[TMP1]], i32 [[TMP5]]
// CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x float> [[TMP4]], float [[TMP6]], i32 1
// CHECK-NEXT: [[TMP8:%.*]] = add i32 6, [[TMP0]]
// CHECK-NEXT: [[TMP9:%.*]] = extractelement <9 x float> [[TMP1]], i32 [[TMP8]]
// CHECK-NEXT: [[TMP10:%.*]] = insertelement <4 x float> [[TMP7]], float [[TMP9]], i32 2
// CHECK-NEXT: [[TMP11:%.*]] = add i32 0, [[TMP0]]
// CHECK-NEXT: [[TMP12:%.*]] = extractelement <9 x float> [[TMP1]], i32 [[TMP11]]
// CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x float> [[TMP10]], float [[TMP12]], i32 3
// CHECK-NEXT: ret <4 x float> [[TMP13]]
//
float4 getMatrix(float3x3 M, int index) {
return M[index].rgbr;
}
// CHECK-LABEL: define hidden noundef <3 x i32> @_Z19getMatrixSwizzle2x3Ru11matrix_typeILm2ELm3EiEi(
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(24) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP2:%.*]] = load <6 x i32>, ptr [[TMP0]], align 4
// CHECK-NEXT: [[TMP3:%.*]] = add i32 4, [[TMP1]]
// CHECK-NEXT: [[TMP4:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP3]]
// CHECK-NEXT: [[TMP5:%.*]] = insertelement <3 x i32> poison, i32 [[TMP4]], i32 0
// CHECK-NEXT: [[TMP6:%.*]] = add i32 0, [[TMP1]]
// CHECK-NEXT: [[TMP7:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP6]]
// CHECK-NEXT: [[TMP8:%.*]] = insertelement <3 x i32> [[TMP5]], i32 [[TMP7]], i32 1
// CHECK-NEXT: [[TMP9:%.*]] = add i32 2, [[TMP1]]
// CHECK-NEXT: [[TMP10:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP9]]
// CHECK-NEXT: [[TMP11:%.*]] = insertelement <3 x i32> [[TMP8]], i32 [[TMP10]], i32 2
// CHECK-NEXT: ret <3 x i32> [[TMP11]]
//
int3 getMatrixSwizzle2x3(out int2x3 M, int index) {
return M[index].brg;
}
// CHECK-LABEL: define hidden void @_Z26setMatrixSwizzleFromMatrixRu11matrix_typeILm2ELm3EiES_i(
// CHECK-SAME: ptr noalias noundef nonnull align 4 dereferenceable(24) [[M:%.*]], <6 x i32> noundef [[N:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[N_ADDR:%.*]] = alloca [2 x <3 x i32>], align 4
// CHECK-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: store ptr [[M]], ptr [[M_ADDR]], align 4
// CHECK-NEXT: store <6 x i32> [[N]], ptr [[N_ADDR]], align 4
// CHECK-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[N_ADDR]], align 4
// CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP0]]
// CHECK-NEXT: [[MATRIX_ELEM:%.*]] = extractelement <6 x i32> [[TMP1]], i32 [[TMP2]]
// CHECK-NEXT: [[MATRIX_ROW_INS:%.*]] = insertelement <3 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
// CHECK-NEXT: [[TMP3:%.*]] = add i32 2, [[TMP0]]
// CHECK-NEXT: [[MATRIX_ELEM1:%.*]] = extractelement <6 x i32> [[TMP1]], i32 [[TMP3]]
// CHECK-NEXT: [[MATRIX_ROW_INS2:%.*]] = insertelement <3 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
// CHECK-NEXT: [[TMP4:%.*]] = add i32 4, [[TMP0]]
// CHECK-NEXT: [[MATRIX_ELEM3:%.*]] = extractelement <6 x i32> [[TMP1]], i32 [[TMP4]]
// CHECK-NEXT: [[MATRIX_ROW_INS4:%.*]] = insertelement <3 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[M_ADDR]], align 4, !nonnull [[META3]], !align [[META4]]
// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
// CHECK-NEXT: [[TMP7:%.*]] = add i32 4, [[TMP6]]
// CHECK-NEXT: [[TMP8:%.*]] = extractelement <3 x i32> [[MATRIX_ROW_INS4]], i32 0
// CHECK-NEXT: [[TMP9:%.*]] = getelementptr <6 x i32>, ptr [[TMP5]], i32 0, i32 [[TMP7]]
// CHECK-NEXT: store i32 [[TMP8]], ptr [[TMP9]], align 4
// CHECK-NEXT: [[TMP10:%.*]] = add i32 0, [[TMP6]]
// CHECK-NEXT: [[TMP11:%.*]] = extractelement <3 x i32> [[MATRIX_ROW_INS4]], i32 1
// CHECK-NEXT: [[TMP12:%.*]] = getelementptr <6 x i32>, ptr [[TMP5]], i32 0, i32 [[TMP10]]
// CHECK-NEXT: store i32 [[TMP11]], ptr [[TMP12]], align 4
// CHECK-NEXT: [[TMP13:%.*]] = add i32 2, [[TMP6]]
// CHECK-NEXT: [[TMP14:%.*]] = extractelement <3 x i32> [[MATRIX_ROW_INS4]], i32 2
// CHECK-NEXT: [[TMP15:%.*]] = getelementptr <6 x i32>, ptr [[TMP5]], i32 0, i32 [[TMP13]]
// CHECK-NEXT: store i32 [[TMP14]], ptr [[TMP15]], align 4
// CHECK-NEXT: ret void
//
void setMatrixSwizzleFromMatrix(out int2x3 M, int2x3 N, int index) {
M[index].brg = N[index];
}
//.
// CHECK: [[META3]] = !{}
// CHECK: [[META4]] = !{i64 4}
//.