Sfoglia il codice sorgente

Bitcast for 16bit types (#817)

This change adds bitcast intrinsics for 16bit types (asfloat16, asint, asuint)
Young Kim 7 anni fa
parent
commit
289d09e700

+ 3 - 0
include/dxc/HlslIntrinsicOp.h

@@ -87,9 +87,12 @@ import hctdb_instrhelp
   IOP_any,
   IOP_asdouble,
   IOP_asfloat,
+  IOP_asfloat16,
   IOP_asin,
   IOP_asint,
+  IOP_asint16,
   IOP_asuint,
+  IOP_asuint16,
   IOP_atan,
   IOP_atan2,
   IOP_ceil,

+ 5 - 2
include/dxc/dxcapi.internal.h

@@ -78,9 +78,12 @@ enum LEGAL_INTRINSIC_COMPTYPES {
   LICOMPTYPE_WAVE = 24,
   LICOMPTYPE_UINT64 = 25,         // u64, int-literal
   LICOMPTYPE_UINT32_64 = 26,      // u32, u64, int-literal
-  LICOMPTYPE_HALF = 27,
+  LICOMPTYPE_FLOAT16 = 27,
+  LICOMPTYPE_INT16 = 28,
+  LICOMPTYPE_UINT16 = 29,
+  LICOMPTYPE_NUMERIC16_ONLY = 30,
 
-  LICOMPTYPE_COUNT = 28
+  LICOMPTYPE_COUNT = 31
 };
 
 static const BYTE IA_SPECIAL_BASE = 0xf0;

+ 3 - 0
lib/HLSL/HLOperationLower.cpp

@@ -4328,9 +4328,12 @@ IntrinsicLower gLowerTable[static_cast<unsigned>(IntrinsicOp::Num_Intrinsics)] =
     {IntrinsicOp::IOP_any, TranslateAny, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_asdouble, TranslateAsDouble, DXIL::OpCode::MakeDouble},
     {IntrinsicOp::IOP_asfloat, TranslateBitcast, DXIL::OpCode::NumOpCodes},
+    {IntrinsicOp::IOP_asfloat16, TranslateBitcast, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_asin, TrivialUnaryOperation, DXIL::OpCode::Asin},
     {IntrinsicOp::IOP_asint, TranslateBitcast, DXIL::OpCode::NumOpCodes},
+    {IntrinsicOp::IOP_asint16, TranslateBitcast, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_asuint, TranslateAsUint, DXIL::OpCode::SplitDouble},
+    {IntrinsicOp::IOP_asuint16, TranslateAsUint, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_atan, TrivialUnaryOperation, DXIL::OpCode::Atan},
     {IntrinsicOp::IOP_atan2, TranslateAtan2, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_ceil, TrivialUnaryOperation, DXIL::OpCode::Round_pi},

+ 31 - 3
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -1068,13 +1068,38 @@ static const ArBasicKind g_UInt3264CT[] =
   AR_BASIC_UNKNOWN
 };
 
-static const ArBasicKind g_HalfCT[] =
+static const ArBasicKind g_Float16CT[] =
 {
   AR_BASIC_FLOAT16,
   AR_BASIC_LITERAL_FLOAT,
   AR_BASIC_UNKNOWN
 };
 
+static const ArBasicKind g_Int16CT[] =
+{
+  AR_BASIC_INT16,
+  AR_BASIC_LITERAL_INT,
+  AR_BASIC_UNKNOWN
+};
+
+static const ArBasicKind g_UInt16CT[] =
+{
+  AR_BASIC_UINT16,
+  AR_BASIC_LITERAL_INT,
+  AR_BASIC_UNKNOWN
+};
+
+static const ArBasicKind g_Numeric16OnlyCT[] =
+{
+  AR_BASIC_FLOAT16,
+  AR_BASIC_INT16,
+  AR_BASIC_UINT16,
+  AR_BASIC_LITERAL_FLOAT,
+  AR_BASIC_LITERAL_INT,
+  AR_BASIC_NOCAST,
+  AR_BASIC_UNKNOWN
+};
+
 // Basic kinds, indexed by a LEGAL_INTRINSIC_COMPTYPES value.
 const ArBasicKind* g_LegalIntrinsicCompTypes[] =
 {
@@ -1105,7 +1130,10 @@ const ArBasicKind* g_LegalIntrinsicCompTypes[] =
   g_WaveCT,             // LICOMPTYPE_WAVE
   g_UInt64CT,           // LICOMPTYPE_UINT64
   g_UInt3264CT,         // LICOMPTYPE_UINT32_64
-  g_HalfCT              // LICOMPTYPE_HALF
+  g_Float16CT,          // LICOMPTYPE_FLOAT16
+  g_Int16CT,            // LICOMPTYPE_INT16
+  g_UInt16CT,           // LICOMPTYPE_UINT16
+  g_Numeric16OnlyCT     // LICOMPTYPE_NUMERIC16_ONLY
 };
 C_ASSERT(ARRAYSIZE(g_LegalIntrinsicCompTypes) == LICOMPTYPE_COUNT);
 
@@ -4959,7 +4987,7 @@ bool HLSLExternalSource::MatchArguments(
         if (AR_BASIC_UNKNOWN == ComponentType[pIntrinsic->pArgs[0].uComponentTypeId]) {
           // half return type should map to float for min precision
           if (pIntrinsic->pArgs[0].uLegalComponentTypes ==
-                  LEGAL_INTRINSIC_COMPTYPES::LICOMPTYPE_HALF &&
+                  LEGAL_INTRINSIC_COMPTYPES::LICOMPTYPE_FLOAT16 &&
               getSema()->getLangOpts().UseMinPrecision) {
             ComponentType[pIntrinsic->pArgs[0].uComponentTypeId] =
               ArBasicKind::AR_BASIC_FLOAT32;

File diff suppressed because it is too large
+ 228 - 207
tools/clang/lib/Sema/gen_intrin_main_tables_15.h


+ 25 - 0
tools/clang/test/CodeGenHLSL/bitcast.hlsl

@@ -0,0 +1,25 @@
+// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+
+// CHECK: bitcast float %{{.*}} to i32
+// CHECK: bitcast i32 %{{.*}} to float
+
+float4 g_f4;
+int4   g_i4;
+uint4  g_u4;
+
+float4 main() : SV_Target
+{
+    float4 f1 = asfloat(g_f4);
+    uint4 u1 = asuint(g_f4);
+    int4 i1 = asint(g_f4);
+
+    f1 += asfloat(g_i4);
+    u1 += asuint(g_i4);
+    i1 += asint(g_i4);
+
+    f1 += asfloat(g_u4);
+    u1 += asuint(g_u4);
+    i1 += asint(g_u4);
+
+    return f1 + u1 + i1;
+}

+ 25 - 0
tools/clang/test/CodeGenHLSL/bitcast_16bits.hlsl

@@ -0,0 +1,25 @@
+// RUN: %dxc -E main -T ps_6_2 -HV 2018 -enable-16bit-types %s | FileCheck %s
+
+// CHECK: bitcast half %{{.*}} to i16
+// CHECK: bitcast i16 %{{.*}} to half
+
+float16_t g_h4;
+int16_t4 g_i4;
+uint16_t4 g_u4;
+
+float4 main(float4 col : COL) : SV_TARGET
+{
+    float16_t4 h1 = asfloat16(g_h4);
+    uint16_t4 u1 = asuint16(g_h4);
+    int16_t4 i1 = asint16(g_h4);
+
+    h1 += asfloat16(g_i4);
+    u1 += asuint16(g_i4);
+    i1 += asint16(g_i4);
+
+    h1 += asfloat16(g_u4);
+    u1 += asuint16(g_u4);
+    i1 += asint16(g_u4);
+
+    return h1 + u1 + i1;
+}

+ 89 - 0
tools/clang/test/HLSL/intrinsic-examples.hlsl

@@ -76,6 +76,95 @@ float4 RWByteAddressBufferMain(uint2 a : A, uint2 b : B) : SV_Target
   return r;
 }
 
+// BitCast intrinsics
+float4 g_f;
+int4 g_i;
+uint4 g_u;
+float16_t4 g_f16;
+int16_t4 g_i16;
+uint16_t4 g_u16;
+float64_t4 g_f64;
+int64_t4 g_i64;
+uint64_t4 g_u64;
+
+// TODO: currently compiler is not handling intrinsics correctly after we found overloaded intrinsic function before.
+// Uncomment errors below after fixing it.
+float4 BitCastMain() : SV_Target {
+  float4 f1 = 0;
+  f1 += asfloat(g_f);
+  f1 += asfloat(g_i);
+  f1 += asfloat(g_u);
+  /*
+  f1 += asfloat(g_f16);
+  f1 += asfloat(g_i16);
+  f1 += asfloat(g_u16);
+  f1 += asfloat(g_f64);
+  f1 += asfloat(g_i64);
+  f1 += asfloat(g_u64);
+*/
+  int4 i1 = 0;
+  i1 += asint(g_f);
+  i1 += asint(g_i);
+  i1 += asint(g_u);
+  /*
+  i1 += asint(g_f16);
+  i1 += asint(g_i16);
+  i1 += asint(g_u16);
+  i1 += asint(g_f64);
+  i1 += asint(g_i64);
+  i1 += asint(g_u64);
+*/
+  uint4 ui1 = 0;
+  ui1 += asuint(g_f);
+  ui1 += asuint(g_i);
+  ui1 += asuint(g_u);
+  /*
+  ui1 += asuint(g_f16);
+  ui1 += asuint(g_i16);
+  ui1 += asuint(g_u16);
+  ui1 += asuint(g_f64);
+  ui1 += asuint(g_i64);
+  ui1 += asuint(g_u64);
+*/
+  float16_t4 f16_1 = 0;
+  f16_1 += asfloat16(g_f16);
+  f16_1 += asfloat16(g_i16);
+  f16_1 += asfloat16(g_u16);
+ /*f16_1 += asfloat16(g_f);
+  f16_1 += asfloat16(g_i);
+  f16_1 += asfloat16(g_u);
+  f16_1 += asfloat16(g_f64);
+  f16_1 += asfloat16(g_i64);
+  f16_1 += asfloat16(g_u64);
+  */
+
+  int16_t4 i16_1 = 0;
+  i16_1 += asint16(g_f16);
+  i16_1 += asint16(g_i16);
+  i16_1 += asint16(g_u16);
+  /*
+  i16_1 += asint16(g_f);
+  i16_1 += asint16(g_i);
+  i16_1 += asint16(g_u);
+  i16_1 += asint16(g_f64);
+  i16_1 += asint16(g_i64);
+  i16_1 += asint16(g_u64);
+*/
+  uint16_t4 u16_1 = 0;
+  u16_1 += asuint16(g_f16);
+  u16_1 += asuint16(g_i16);
+  u16_1 += asuint16(g_u16);
+  /*
+  u16_1 += asuint16(g_f);
+  u16_1 += asuint16(g_i);
+  u16_1 += asuint16(g_u);
+  u16_1 += asuint16(g_f64);
+  u16_1 += asuint16(g_i64);
+  i16_1 += asuint16(g_u64);
+*/
+}
+
+
 // The following sample includes tex2D mixing new and old style of sampler types.
 
 //--------------------------------------------------------------------------------------

+ 11 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -477,6 +477,8 @@ public:
   TEST_METHOD(CodeGenBarycentrics1)
   TEST_METHOD(CodeGenBarycentricsThreeSV)
   TEST_METHOD(CodeGenBinary1)
+  TEST_METHOD(CodeGenBitCast)
+  TEST_METHOD(CodeGenBitCast16Bits)
   TEST_METHOD(CodeGenBoolComb)
   TEST_METHOD(CodeGenBoolSvTarget)
   TEST_METHOD(CodeGenCalcLod2DArray)
@@ -3074,6 +3076,15 @@ TEST_F(CompilerTest, CodeGenBinary1) {
   CodeGenTest(L"..\\CodeGenHLSL\\binary1.hlsl");
 }
 
+TEST_F(CompilerTest, CodeGenBitCast) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\bitcast.hlsl");
+}
+
+TEST_F(CompilerTest, CodeGenBitCast16Bits) {
+  if (m_ver.SkipDxilVersion(1, 2)) return;
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\bitcast_16bits.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenBoolComb) {
   CodeGenTest(L"..\\CodeGenHLSL\\boolComb.hlsl");
 }

+ 2 - 2
tools/clang/unittests/HLSL/ExtensionTest.cpp

@@ -731,11 +731,11 @@ TEST_F(ExtensionTest, UnsignedOpcodeIsUnchanged) {
 
   // - opcode is unchanged when it matches an hlsl intrinsic with
   //   an unsigned version.
-  // Note that 114 is the current opcode for IOP_min. If that opcode
+  // Note that 117 is the current opcode for IOP_min. If that opcode
   // changes the test will need to be updated to reflect the new opcode.
   VERIFY_IS_TRUE(
     disassembly.npos !=
-    disassembly.find("call i32 @test_unsigned(i32 114, "));
+    disassembly.find("call i32 @test_unsigned(i32 117, "));
 }
 
 TEST_F(ExtensionTest, ResourceExtensionIntrinsic) {

+ 3 - 0
utils/hct/gen_intrin_main.txt

@@ -91,10 +91,13 @@ void [[]] AllMemoryBarrierWithGroupSync() : syncgroupandallmemory_ug;
 bool [[rn]] any(in any<> x);
 double<> [[rn]] asdouble(in $match<0, 1> uint_only<> x, in $match<0, 2> uint_only<> y) : reinterpret_fuse_double;
 float<> [[rn]] asfloat(in $match<0, 1> numeric32_only<> x) : reinterpret_float;
+float16_t<> [[rn]] asfloat16(in $match<0,1> numeric16_only<> x) : reinterpret_float16;
+int16_t<> [[rn]] asint16(in $match<0,1> numeric16_only<> x) : reinterpret_int16;
 $type1 [[rn]] asin(in float_like<> x);
 int<> [[rn]] asint(in $match<0, 1> numeric32_only<> x) : reinterpret_int;
 void [[]] asuint(in double<> d, out $match<1, 2> uint<> x, out $match<1, 3> uint<> y) : reinterpret_split_double_uint;
 uint<> [[rn]] asuint(in $match<0, 1> numeric32_only<> x) : reinterpret_uint;
+uint16_t<> [[rn]] asuint16(in $match<0,1> numeric16_only<> x) : reinterpret_uint16;
 $type1 [[rn]] atan(in float_like<> x);
 $type1 [[rn]] atan2(in float_like<> x, in $type1 y);
 $type1 [[rn]] ceil(in float_like<> x);

+ 4 - 1
utils/hct/hctdb.py

@@ -1919,13 +1919,15 @@ class db_hlsl(object):
         self.base_types = {
             "bool": "LICOMPTYPE_BOOL",
             "int": "LICOMPTYPE_INT",
+            "int16_t": "LICOMPTYPE_INT16",
             "uint": "LICOMPTYPE_UINT",
+            "uint16_t": "LICOMPTYPE_UINT16",
             "u64": "LICOMPTYPE_UINT64",
             "u32_64": "LICOMPTYPE_UINT32_64",
             "any_int": "LICOMPTYPE_ANY_INT",
             "any_int32": "LICOMPTYPE_ANY_INT32",
             "uint_only": "LICOMPTYPE_UINT_ONLY",
-            "half": "LICOMPTYPE_HALF",
+            "float16_t": "LICOMPTYPE_FLOAT16",
             "float": "LICOMPTYPE_FLOAT",
             "fldbl": "LICOMPTYPE_FLOAT_DOUBLE",
             "any_float": "LICOMPTYPE_ANY_FLOAT",
@@ -1933,6 +1935,7 @@ class db_hlsl(object):
             "double": "LICOMPTYPE_DOUBLE",
             "double_only": "LICOMPTYPE_DOUBLE_ONLY",
             "numeric": "LICOMPTYPE_NUMERIC",
+            "numeric16_only": "LICOMPTYPE_NUMERIC16_ONLY",
             "numeric32": "LICOMPTYPE_NUMERIC32",
             "numeric32_only": "LICOMPTYPE_NUMERIC32_ONLY",
             "any": "LICOMPTYPE_ANY",

Some files were not shown because too many files changed in this diff