Files
llvm-tms34010/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptDynamicSwizzle.hlsl
Finn Plummer 461f816d44 Reland "[HLSL][DirectX] Emit convergence control tokens when targeting DirectX" (#194452)
The initial landing surfaced 3 somewhat orthogonal issues related to
loop unrolling. These are addressed:
[here](https://github.com/llvm/llvm-project/pull/193592),
[here](https://github.com/llvm/llvm-project/pull/193593) and
[here](https://github.com/llvm/llvm-project/pull/193590).

These caused these
[tests](https://github.com/llvm/llvm-project/actions/runs/24577221310/job/71865579618#step:8:87913)
to fail in the offload test suite.

We can verify that these are now passing as expected (fixing any of the
3 issues would resolve this and allow us to reland)

Some additional tests were added since the revert that are now accounted
for and updated in the reland fixes commit.

This relands https://github.com/llvm/llvm-project/pull/188792
2026-05-26 11:55:15 -07:00

162 lines
10 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: %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.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 4
// 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 4
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[V_ADDR]], align 4
// 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: %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.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: %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.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: %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.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: %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
// CHECK-NEXT: [[M_ADDR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[N_ADDR:%.*]] = alloca [3 x <2 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}
//.