blob: 54e9aa83cda0b6f8b95a9a36c56fbf08e7dd11ce [file] [edit]
// Per-row store.output emission for the range of semantic leaf types:
// float - scalar -> 1 row
// float4 - vector -> 1 row (4 columns)
// float[5] - scalar array -> 5 rows
// float4[2][3] - vector array -> 6 rows (multidimensional, 4 columns each)
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
struct S {
float a : A;
float4 b : B;
float d[5] : D;
float4 e[2][3] : E;
};
[shader("vertex")]
S main() {
S s;
return s;
}
// float a : A -> 1 row, 1 column.
// CHECK: %[[A:.*]] = extractvalue %struct.S %[[S:.*]], 0
// CHECK: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[A]])
// float4 b : B -> 1 row, 4 columns; the whole vector is stored.
// CHECK: %[[B:.*]] = extractvalue %struct.S %[[S]], 1
// CHECK: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[B]])
// float d[5] : D -> 5 rows, 1 column each.
// CHECK: %[[D:.*]] = extractvalue %struct.S %[[S]], 2
// CHECK: %[[D0:.*]] = extractvalue [5 x float] %[[D]], 0
// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 0, i8 0, float %[[D0]])
// CHECK: %[[D1:.*]] = extractvalue [5 x float] %[[D]], 1
// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 1, i8 0, float %[[D1]])
// CHECK: %[[D2:.*]] = extractvalue [5 x float] %[[D]], 2
// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 2, i8 0, float %[[D2]])
// CHECK: %[[D3:.*]] = extractvalue [5 x float] %[[D]], 3
// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 3, i8 0, float %[[D3]])
// CHECK: %[[D4:.*]] = extractvalue [5 x float] %[[D]], 4
// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 4, i8 0, float %[[D4]])
// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
// CHECK: %[[E:.*]] = extractvalue %struct.S %[[S]], 3
// CHECK: %[[E00:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 0
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 0, i8 0, <4 x float> %[[E00]])
// CHECK: %[[E01:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 1
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 1, i8 0, <4 x float> %[[E01]])
// CHECK: %[[E02:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 2
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 2, i8 0, <4 x float> %[[E02]])
// CHECK: %[[E10:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 0
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 3, i8 0, <4 x float> %[[E10]])
// CHECK: %[[E11:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 1
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 4, i8 0, <4 x float> %[[E11]])
// CHECK: %[[E12:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 2
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 5, i8 0, <4 x float> %[[E12]])
// CHECK: !dx.semantic.signatures = !{![[#ENTRY_SIG:]]}
// CHECK: ![[#ENTRY_SIG]] = !{ptr @main, null, ![[#OUTPUT_SIG:]]}
// CHECK: ![[#OUTPUT_SIG]] = !{![[#A_SIG:]], ![[#B_SIG:]], ![[#D_SIG:]], ![[#E_SIG:]]}
// CHECK: ![[#A_SIG]] = !{i32 0, !"A", i32 9, i32 0, ![[#ZERO_INDEX:]], i32 0, i32 1, i8 1, i32 -1, i8 -1, i8 0, i8 0, i32 0}
// CHECK: ![[#ZERO_INDEX]] = !{i32 0}
// CHECK: ![[#B_SIG]] = !{i32 1, !"B", i32 9, i32 0, ![[#ZERO_INDEX]], i32 0, i32 1, i8 4, i32 -1, i8 -1, i8 0, i8 0, i32 0}
// CHECK: ![[#D_SIG]] = !{i32 2, !"D", i32 9, i32 0, ![[#D_INDICES:]], i32 0, i32 5, i8 1, i32 -1, i8 -1, i8 0, i8 0, i32 0}
// CHECK: ![[#D_INDICES]] = !{i32 0, i32 1, i32 2, i32 3, i32 4}
// CHECK: ![[#E_SIG]] = !{i32 3, !"E", i32 9, i32 0, ![[#E_INDICES:]], i32 0, i32 6, i8 4, i32 -1, i8 -1, i8 0, i8 0, i32 0}
// CHECK: ![[#E_INDICES]] = !{i32 0, i32 1, i32 2, i32 3, i32 4, i32 5}