Skip to content

Commit aaa30e2

Browse files
[SPIRV] Support 16-bit Type Cast Intrinsics (microsoft#4679)
* [SPIRV] Support 16-bit Type Cast Intrinsics This change adds support for 16-bit type cast intrinsics by routing them into the same logic used by the 32-bit type casts. With this change in place, asfloat16, asint16, and asuint16 are now translated into OpBitcast in SPIR-V. This change also includes new partial disassembly tests for each function similar to the ones used for 32-bit casts. * Update Comments in processIntrinsicsAsType This commit updates the comments at the top of processIntrinsicsAsType in order to indicate that this function also supports the 16-bit variants of the type casting intrinsics.
1 parent dc5949e commit aaa30e2

File tree

5 files changed

+210
-1
lines changed

5 files changed

+210
-1
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7969,8 +7969,11 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
79697969
break;
79707970
case hlsl::IntrinsicOp::IOP_asdouble:
79717971
case hlsl::IntrinsicOp::IOP_asfloat:
7972+
case hlsl::IntrinsicOp::IOP_asfloat16:
79727973
case hlsl::IntrinsicOp::IOP_asint:
7974+
case hlsl::IntrinsicOp::IOP_asint16:
79737975
case hlsl::IntrinsicOp::IOP_asuint:
7976+
case hlsl::IntrinsicOp::IOP_asuint16:
79747977
retVal = processIntrinsicAsType(callExpr);
79757978
break;
79767979
case hlsl::IntrinsicOp::IOP_clip:
@@ -10106,7 +10109,18 @@ SpirvEmitter::processIntrinsicAllOrAny(const CallExpr *callExpr,
1010610109

1010710110
SpirvInstruction *
1010810111
SpirvEmitter::processIntrinsicAsType(const CallExpr *callExpr) {
10109-
// This function handles 'asint', 'asuint', 'asfloat', and 'asdouble'.
10112+
// This function handles the following intrinsics:
10113+
// 'asint'
10114+
// 'asint16'
10115+
// 'asuint'
10116+
// 'asuint16'
10117+
// 'asfloat'
10118+
// 'asfloat16'
10119+
// 'asdouble'
10120+
10121+
// Note: The logic for the 32-bit and 16-bit variants of these functions is
10122+
// identical so we don't bother distinguishing between related types
10123+
// like float and float16 in the comments.
1011010124

1011110125
// Method 1: ret asint(arg)
1011210126
// arg component type = {float, uint}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types
2+
3+
// CHECK: OpCapability Float16
4+
// CHECK: OpCapability Int16
5+
6+
void main() {
7+
float16_t result;
8+
float16_t4 result4;
9+
10+
// CHECK: [[a:%\d+]] = OpLoad %short %a
11+
// CHECK-NEXT: [[a_as_half:%\d+]] = OpBitcast %half [[a]]
12+
// CHECK-NEXT: OpStore %result [[a_as_half]]
13+
int16_t a;
14+
result = asfloat16(a);
15+
16+
// CHECK-NEXT: [[b:%\d+]] = OpLoad %ushort %b
17+
// CHECK-NEXT: [[b_as_half:%\d+]] = OpBitcast %half [[b]]
18+
// CHECK-NEXT: OpStore %result [[b_as_half]]
19+
uint16_t b;
20+
result = asfloat16(b);
21+
22+
// CHECK-NEXT: [[c:%\d+]] = OpLoad %half %c
23+
// CHECK-NEXT: OpStore %result [[c]]
24+
float16_t c;
25+
result = asfloat16(c);
26+
27+
// CHECK-NEXT: [[d:%\d+]] = OpLoad %v4short %d
28+
// CHECK-NEXT: [[d_as_half:%\d+]] = OpBitcast %v4half [[d]]
29+
// CHECK-NEXT: OpStore %result4 [[d_as_half]]
30+
int16_t4 d;
31+
result4 = asfloat16(d);
32+
33+
// CHECK-NEXT: [[e:%\d+]] = OpLoad %v4ushort %e
34+
// CHECK-NEXT: [[e_as_half:%\d+]] = OpBitcast %v4half [[e]]
35+
// CHECK-NEXT: OpStore %result4 [[e_as_half]]
36+
uint16_t4 e;
37+
result4 = asfloat16(e);
38+
39+
// CHECK-NEXT: [[f:%\d+]] = OpLoad %v4half %f
40+
// CHECK-NEXT: OpStore %result4 [[f]]
41+
float16_t4 f;
42+
result4 = asfloat16(f);
43+
44+
int16_t2x3 intMat;
45+
uint16_t2x3 uintMat;
46+
47+
// CHECK: [[intMat:%\d+]] = OpLoad %_arr_v3short_uint_2 %intMat
48+
// CHECK-NEXT: [[intMat0:%\d+]] = OpCompositeExtract %v3short [[intMat]] 0
49+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3half [[intMat0]]
50+
// CHECK-NEXT: [[intMat1:%\d+]] = OpCompositeExtract %v3short [[intMat]] 1
51+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3half [[intMat1]]
52+
// CHECK-NEXT: [[g:%\d+]] = OpCompositeConstruct %mat2v3half [[row0]] [[row1]]
53+
// CHECK-NEXT: OpStore %g [[g]]
54+
float16_t2x3 g = asfloat16(intMat);
55+
56+
// CHECK: [[uintMat:%\d+]] = OpLoad %_arr_v3ushort_uint_2 %uintMat
57+
// CHECK-NEXT: [[uintMat0:%\d+]] = OpCompositeExtract %v3ushort [[uintMat]] 0
58+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3half [[uintMat0]]
59+
// CHECK-NEXT: [[uintMat1:%\d+]] = OpCompositeExtract %v3ushort [[uintMat]] 1
60+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3half [[uintMat1]]
61+
// CHECK-NEXT: [[h:%\d+]] = OpCompositeConstruct %mat2v3half [[row0]] [[row1]]
62+
// CHECK-NEXT: OpStore %h [[h]]
63+
float16_t2x3 h = asfloat16(uintMat);
64+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types
2+
3+
// CHECK: OpCapability Int16
4+
// CHECK: OpCapability Float16
5+
6+
void main() {
7+
int16_t result;
8+
int16_t4 result4;
9+
10+
// CHECK: [[a:%\d+]] = OpLoad %short %a
11+
// CHECK-NEXT: OpStore %result [[a]]
12+
int16_t a;
13+
result = asint16(a);
14+
15+
// CHECK: [[b:%\d+]] = OpLoad %ushort %b
16+
// CHECK-NEXT: [[b_as_short:%\d+]] = OpBitcast %short [[b]]
17+
// CHECK-NEXT: OpStore %result [[b_as_short]]
18+
uint16_t b;
19+
result = asint16(b);
20+
21+
// CHECK: [[c:%\d+]] = OpLoad %half %c
22+
// CHECK-NEXT: [[c_as_short:%\d+]] = OpBitcast %short [[c]]
23+
// CHECK-NEXT: OpStore %result [[c_as_short]]
24+
float16_t c;
25+
result = asint16(c);
26+
27+
// CHECK: [[d:%\d+]] = OpLoad %v4short %d
28+
// CHECK-NEXT: OpStore %result4 [[d]]
29+
int16_t4 d;
30+
result4 = asint16(d);
31+
32+
// CHECK: [[e:%\d+]] = OpLoad %v4ushort %e
33+
// CHECK-NEXT: [[e_as_short:%\d+]] = OpBitcast %v4short [[e]]
34+
// CHECK-NEXT: OpStore %result4 [[e_as_short]]
35+
uint16_t4 e;
36+
result4 = asint16(e);
37+
38+
// CHECK: [[f:%\d+]] = OpLoad %v4half %f
39+
// CHECK-NEXT: [[f_as_short:%\d+]] = OpBitcast %v4short [[f]]
40+
// CHECK-NEXT: OpStore %result4 [[f_as_short]]
41+
float16_t4 f;
42+
result4 = asint16(f);
43+
44+
float16_t2x3 floatMat;
45+
uint16_t2x3 uintMat;
46+
47+
// CHECK: [[floatMat:%\d+]] = OpLoad %mat2v3half %floatMat
48+
// CHECK-NEXT: [[floatMat0:%\d+]] = OpCompositeExtract %v3half [[floatMat]] 0
49+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3short [[floatMat0]]
50+
// CHECK-NEXT: [[floatMat1:%\d+]] = OpCompositeExtract %v3half [[floatMat]] 1
51+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3short [[floatMat1]]
52+
// CHECK-NEXT: [[g:%\d+]] = OpCompositeConstruct %_arr_v3short_uint_2 [[row0]] [[row1]]
53+
// CHECK-NEXT: OpStore %g [[g]]
54+
int16_t2x3 g = asint16(floatMat);
55+
56+
// CHECK: [[uintMat:%\d+]] = OpLoad %_arr_v3ushort_uint_2 %uintMat
57+
// CHECK-NEXT: [[uintMat0:%\d+]] = OpCompositeExtract %v3ushort [[uintMat]] 0
58+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3short [[uintMat0]]
59+
// CHECK-NEXT: [[uintMat1:%\d+]] = OpCompositeExtract %v3ushort [[uintMat]] 1
60+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3short [[uintMat1]]
61+
// CHECK-NEXT: [[h:%\d+]] = OpCompositeConstruct %_arr_v3short_uint_2 [[row0]] [[row1]]
62+
// CHECK-NEXT: OpStore %h [[h]]
63+
int16_t2x3 h = asint16(uintMat);
64+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types
2+
3+
// CHECK: OpCapability Int16
4+
// CHECK: OpCapability Float16
5+
6+
void main() {
7+
uint16_t result;
8+
uint16_t4 result4;
9+
10+
// CHECK: [[a:%\d+]] = OpLoad %short %a
11+
// CHECK-NEXT: [[a_as_ushort:%\d+]] = OpBitcast %ushort [[a]]
12+
// CHECK-NEXT: OpStore %result [[a_as_ushort]]
13+
int16_t a;
14+
result = asuint16(a);
15+
16+
// CHECK: [[b:%\d+]] = OpLoad %ushort %b
17+
// CHECK-NEXT: OpStore %result [[b]]
18+
uint16_t b;
19+
result = asuint16(b);
20+
21+
// CHECK: [[c:%\d+]] = OpLoad %half %c
22+
// CHECK-NEXT: [[c_as_ushort:%\d+]] = OpBitcast %ushort [[c]]
23+
// CHECK-NEXT: OpStore %result [[c_as_ushort]]
24+
float16_t c;
25+
result = asuint16(c);
26+
27+
// CHECK: [[d:%\d+]] = OpLoad %v4short %d
28+
// CHECK-NEXT: [[d_as_ushort:%\d+]] = OpBitcast %v4ushort [[d]]
29+
// CHECK-NEXT: OpStore %result4 [[d_as_ushort]]
30+
int16_t4 d;
31+
result4 = asuint16(d);
32+
33+
// CHECK: [[e:%\d+]] = OpLoad %v4ushort %e
34+
// CHECK-NEXT: OpStore %result4 [[e]]
35+
uint16_t4 e;
36+
result4 = asuint16(e);
37+
38+
// CHECK: [[f:%\d+]] = OpLoad %v4half %f
39+
// CHECK-NEXT: [[f_as_ushort:%\d+]] = OpBitcast %v4ushort [[f]]
40+
// CHECK-NEXT: OpStore %result4 [[f_as_ushort]]
41+
float16_t4 f;
42+
result4 = asuint16(f);
43+
44+
float16_t2x3 floatMat;
45+
int16_t2x3 intMat;
46+
47+
// CHECK: [[floatMat:%\d+]] = OpLoad %mat2v3half %floatMat
48+
// CHECK-NEXT: [[floatMat0:%\d+]] = OpCompositeExtract %v3half [[floatMat]] 0
49+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3ushort [[floatMat0]]
50+
// CHECK-NEXT: [[floatMat1:%\d+]] = OpCompositeExtract %v3half [[floatMat]] 1
51+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3ushort [[floatMat1]]
52+
// CHECK-NEXT: [[g:%\d+]] = OpCompositeConstruct %_arr_v3ushort_uint_2 [[row0]] [[row1]]
53+
// CHECK-NEXT: OpStore %g [[g]]
54+
uint16_t2x3 g = asuint16(floatMat);
55+
56+
// CHECK: [[intMat:%\d+]] = OpLoad %_arr_v3short_uint_2 %intMat
57+
// CHECK-NEXT: [[intMat0:%\d+]] = OpCompositeExtract %v3short [[intMat]] 0
58+
// CHECK-NEXT: [[row0:%\d+]] = OpBitcast %v3ushort [[intMat0]]
59+
// CHECK-NEXT: [[intMat1:%\d+]] = OpCompositeExtract %v3short [[intMat]] 1
60+
// CHECK-NEXT: [[row1:%\d+]] = OpBitcast %v3ushort [[intMat1]]
61+
// CHECK-NEXT: [[h:%\d+]] = OpCompositeConstruct %_arr_v3ushort_uint_2 [[row0]] [[row1]]
62+
// CHECK-NEXT: OpStore %h [[h]]
63+
uint16_t2x3 h = asuint16(intMat);
64+
}

tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,8 +1165,11 @@ TEST_F(FileTest, IntrinsicsAsDouble) {
11651165
runFileTest("intrinsics.asdouble.hlsl");
11661166
}
11671167
TEST_F(FileTest, IntrinsicsAsfloat) { runFileTest("intrinsics.asfloat.hlsl"); }
1168+
TEST_F(FileTest, IntrinsicsAsfloat16) { runFileTest("intrinsics.asfloat16.hlsl"); }
11681169
TEST_F(FileTest, IntrinsicsAsint) { runFileTest("intrinsics.asint.hlsl"); }
1170+
TEST_F(FileTest, IntrinsicsAsint16) { runFileTest("intrinsics.asint16.hlsl"); }
11691171
TEST_F(FileTest, IntrinsicsAsuint) { runFileTest("intrinsics.asuint.hlsl"); }
1172+
TEST_F(FileTest, IntrinsicsAsuint16) { runFileTest("intrinsics.asuint16.hlsl"); }
11701173
TEST_F(FileTest, IntrinsicsAsuintArgumentMustBeRValue) {
11711174
runFileTest("intrinsics.asuint.rvalue.hlsl");
11721175
}

0 commit comments

Comments
 (0)