Browse Source

[spirv] Intrinsic function all, any, asfloat, asint, and asuint (#506)

The current implementation does not support matrix arguments.
Ehsan 8 years ago
parent
commit
8395b98539

+ 70 - 18
tools/clang/lib/SPIRV/EmitSPIRVAction.cpp

@@ -1496,7 +1496,8 @@ public:
   }
 
   uint32_t processIntrinsicDot(const CallExpr *callExpr) {
-    const uint32_t returnType =
+    const QualType returnType = callExpr->getType();
+    const uint32_t returnTypeId =
         typeTranslator.translateType(callExpr->getType());
 
     // Get the function parameters. Expect 2 vectors as parameters.
@@ -1511,29 +1512,25 @@ public:
     const size_t vec1Size = hlsl::GetHLSLVecSize(arg1Type);
     const QualType vec0ComponentType = hlsl::GetHLSLVecElementType(arg0Type);
     const QualType vec1ComponentType = hlsl::GetHLSLVecElementType(arg1Type);
-    assert(callExpr->getType() == vec1ComponentType);
+    assert(returnType == vec1ComponentType);
     assert(vec0ComponentType == vec1ComponentType);
     assert(vec0Size == vec1Size);
     assert(vec0Size >= 1 && vec0Size <= 4);
 
     // According to HLSL reference, the dot function only works on integers
     // and floats.
-    const auto returnTypeBuiltinKind =
-        cast<BuiltinType>(callExpr->getType().getTypePtr())->getKind();
-    assert(returnTypeBuiltinKind == BuiltinType::Float ||
-           returnTypeBuiltinKind == BuiltinType::Int ||
-           returnTypeBuiltinKind == BuiltinType::UInt);
+    assert(returnType->isFloatingType() || returnType->isIntegerType());
 
     // Special case: dot product of two vectors, each of size 1. That is
     // basically the same as regular multiplication of 2 scalars.
     if (vec0Size == 1) {
       const spv::Op spvOp = translateOp(BO_Mul, arg0Type);
-      return theBuilder.createBinaryOp(spvOp, returnType, arg0Id, arg1Id);
+      return theBuilder.createBinaryOp(spvOp, returnTypeId, arg0Id, arg1Id);
     }
 
     // If the vectors are of type Float, we can use OpDot.
-    if (returnTypeBuiltinKind == BuiltinType::Float) {
-      return theBuilder.createBinaryOp(spv::Op::OpDot, returnType, arg0Id,
+    if (returnType->isFloatingType()) {
+      return theBuilder.createBinaryOp(spv::Op::OpDot, returnTypeId, arg0Id,
                                        arg1Id);
     }
     // Vector component type is Integer (signed or unsigned).
@@ -1550,18 +1547,18 @@ public:
       // Extract members from the two vectors and multiply them.
       for (unsigned int i = 0; i < vec0Size; ++i) {
         const uint32_t vec0member =
-            theBuilder.createCompositeExtract(returnType, arg0Id, {i});
+            theBuilder.createCompositeExtract(returnTypeId, arg0Id, {i});
         const uint32_t vec1member =
-            theBuilder.createCompositeExtract(returnType, arg1Id, {i});
+            theBuilder.createCompositeExtract(returnTypeId, arg1Id, {i});
         const uint32_t multId = theBuilder.createBinaryOp(
-            multSpvOp, returnType, vec0member, vec1member);
+            multSpvOp, returnTypeId, vec0member, vec1member);
         multIds.push_back(multId);
       }
       // Add all the multiplications.
       result = multIds[0];
       for (unsigned int i = 1; i < vec0Size; ++i) {
-        const uint32_t additionId =
-            theBuilder.createBinaryOp(addSpvOp, returnType, result, multIds[i]);
+        const uint32_t additionId = theBuilder.createBinaryOp(
+            addSpvOp, returnTypeId, result, multIds[i]);
         result = additionId;
       }
       return result;
@@ -1620,6 +1617,55 @@ public:
     return 0;
   }
 
+  uint32_t processIntrinsicAllOrAny(const CallExpr *callExpr, spv::Op spvOp) {
+    const uint32_t returnType =
+        typeTranslator.translateType(callExpr->getType());
+
+    // 'all' and 'any' take only 1 parameter.
+    assert(callExpr->getNumArgs() == 1u);
+    const Expr *arg = callExpr->getArg(0);
+    const QualType argType = arg->getType();
+
+    if (hlsl::IsHLSLMatType(argType)) {
+      emitError("'all' and 'any' do not support matrix arguments yet.");
+      return 0;
+    }
+
+    bool isSpirvAcceptableVecType =
+        hlsl::IsHLSLVecType(argType) && hlsl::GetHLSLVecSize(argType) > 1;
+    if (!isSpirvAcceptableVecType) {
+      // For a scalar or vector of 1 scalar, we can simply cast to boolean.
+      return castToBool(arg, callExpr->getType());
+    } else {
+      // First cast the vector to a vector of booleans, then use OpAll
+      uint32_t boolVecId = castToBool(arg, callExpr->getType());
+      return theBuilder.createUnaryOp(spvOp, returnType, boolVecId);
+    }
+  }
+
+  /// Processes the 'asfloat', 'asint', and 'asuint' intrinsic functions.
+  uint32_t processIntrinsicAsType(const CallExpr *callExpr) {
+    const QualType returnType = callExpr->getType();
+    const uint32_t returnTypeId = typeTranslator.translateType(returnType);
+    assert(callExpr->getNumArgs() == 1u);
+    const Expr *arg = callExpr->getArg(0);
+    const QualType argType = arg->getType();
+
+    // asfloat may take a float or a float vector or a float matrix as argument.
+    // These cases would be a no-op.
+    if (returnType.getCanonicalType() == argType.getCanonicalType())
+      return doExpr(arg);
+
+    if (hlsl::IsHLSLMatType(argType)) {
+      emitError("'asfloat', 'asint', and 'asuint' do not support matrix "
+                "arguments yet.");
+      return 0;
+    }
+
+    return theBuilder.createUnaryOp(spv::Op::OpBitcast, returnTypeId,
+                                    doExpr(arg));
+  }
+
   uint32_t processIntrinsicCallExpr(const CallExpr *callExpr) {
     const FunctionDecl *callee = callExpr->getDirectCallee();
     assert(hlsl::IsIntrinsicOp(callee) &&
@@ -1631,10 +1677,16 @@ public:
     hlsl::GetIntrinsicOp(callee, opcode, group);
 
     switch (static_cast<hlsl::IntrinsicOp>(opcode)) {
-    case hlsl::IntrinsicOp::IOP_dot: {
+    case hlsl::IntrinsicOp::IOP_dot:
       return processIntrinsicDot(callExpr);
-      break;
-    }
+    case hlsl::IntrinsicOp::IOP_all:
+      return processIntrinsicAllOrAny(callExpr, spv::Op::OpAll);
+    case hlsl::IntrinsicOp::IOP_any:
+      return processIntrinsicAllOrAny(callExpr, spv::Op::OpAny);
+    case hlsl::IntrinsicOp::IOP_asfloat:
+    case hlsl::IntrinsicOp::IOP_asint:
+    case hlsl::IntrinsicOp::IOP_asuint:
+      return processIntrinsicAsType(callExpr);
     default:
       break;
     }

+ 87 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.all.hlsl

@@ -0,0 +1,87 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'all' function can only operate on int, bool, float,
+// vector of these scalars, and matrix of these scalars.
+
+// CHECK:      [[v4int_0:%\d+]] = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+// CHECK-NEXT: [[v4uint_0:%\d+]] = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0
+// CHECK-NEXT: [[v4float_0:%\d+]] = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+
+void main() {
+    bool result;
+
+    // CHECK:      [[a:%\d+]] = OpLoad %int %a
+    // CHECK-NEXT: [[all_int:%\d+]] = OpINotEqual %bool [[a]] %int_0
+    // CHECK-NEXT: OpStore %result [[all_int]]
+    int a;
+    result = all(a);
+
+    // CHECK-NEXT: [[b:%\d+]] = OpLoad %uint %b
+    // CHECK-NEXT: [[all_uint:%\d+]] = OpINotEqual %bool [[b]] %uint_0
+    // CHECK-NEXT: OpStore %result [[all_uint]]
+    uint b;
+    result = all(b);
+
+    // CHECK-NEXT: [[c:%\d+]] = OpLoad %bool %c
+    // CHECK-NEXT: OpStore %result [[c]]
+    bool c;
+    result = all(c);
+
+    // CHECK-NEXT: [[d:%\d+]] = OpLoad %float %d
+    // CHECK-NEXT: [[all_float:%\d+]] = OpFOrdNotEqual %bool [[d]] %float_0
+    // CHECK-NEXT: OpStore %result [[all_float]]
+    float d;
+    result = all(d);
+
+    // CHECK-NEXT: [[e:%\d+]] = OpLoad %int %e
+    // CHECK-NEXT: [[all_int1:%\d+]] = OpINotEqual %bool [[e]] %int_0
+    // CHECK-NEXT: OpStore %result [[all_int1]]
+    int1 e;
+    result = all(e);
+
+    // CHECK-NEXT: [[f:%\d+]] = OpLoad %uint %f
+    // CHECK-NEXT: [[all_uint1:%\d+]] = OpINotEqual %bool [[f]] %uint_0
+    // CHECK-NEXT: OpStore %result [[all_uint1]]
+    uint1 f;
+    result = all(f);
+
+    // CHECK-NEXT: [[g:%\d+]] = OpLoad %bool %g
+    // CHECK-NEXT: OpStore %result [[g]]
+    bool1 g;
+    result = all(g);
+
+    // CHECK-NEXT: [[h:%\d+]] = OpLoad %float %h
+    // CHECK-NEXT: [[all_float1:%\d+]] = OpFOrdNotEqual %bool [[h]] %float_0
+    // CHECK-NEXT: OpStore %result [[all_float1]]
+    float1 h;
+    result = all(h);
+
+    // CHECK-NEXT: [[i:%\d+]] = OpLoad %v4int %i
+    // CHECK-NEXT: [[v4int_to_bool:%\d+]] = OpINotEqual %bool [[i]] [[v4int_0]]
+    // CHECK-NEXT: [[all_int4:%\d+]] = OpAll %bool [[v4int_to_bool]]
+    // CHECK-NEXT: OpStore %result [[all_int4]]
+    int4 i;
+    result = all(i);
+
+    // CHECK-NEXT: [[j:%\d+]] = OpLoad %v4uint %j
+    // CHECK-NEXT: [[v4uint_to_bool:%\d+]] = OpINotEqual %bool [[j]] [[v4uint_0]]
+    // CHECK-NEXT: [[all_uint4:%\d+]] = OpAll %bool [[v4uint_to_bool]]
+    // CHECK-NEXT: OpStore %result [[all_uint4]]
+    uint4 j;
+    result = all(j);
+
+    // CHECK-NEXT: [[k:%\d+]] = OpLoad %v4bool %k
+    // CHECK-NEXT: [[all_bool4:%\d+]] = OpAll %bool [[k]]
+    // CHECK-NEXT: OpStore %result [[all_bool4]]
+    bool4 k;
+    result = all(k);
+
+    // CHECK-NEXT: [[l:%\d+]] = OpLoad %v4float %l
+    // CHECK-NEXT: [[v4float_to_bool:%\d+]] = OpFOrdNotEqual %bool [[l]] [[v4float_0]]
+    // CHECK-NEXT: [[all_float4:%\d+]] = OpAll %bool [[v4float_to_bool]]
+    // CHECK-NEXT: OpStore %result [[all_float4]]
+    float4 l;
+    result = all(l);
+}
+

+ 87 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.any.hlsl

@@ -0,0 +1,87 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'any' function can only operate on int, bool, float,
+// vector of these scalars, and matrix of these scalars.
+
+// CHECK:      [[v4int_0:%\d+]] = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+// CHECK-NEXT: [[v4uint_0:%\d+]] = OpConstantComposite %v4uint %uint_0 %uint_0 %uint_0 %uint_0
+// CHECK-NEXT: [[v4float_0:%\d+]] = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+
+void main() {
+    bool result;
+
+    // CHECK:      [[a:%\d+]] = OpLoad %int %a
+    // CHECK-NEXT: [[any_int:%\d+]] = OpINotEqual %bool [[a]] %int_0
+    // CHECK-NEXT: OpStore %result [[any_int]]
+    int a;
+    result = any(a);
+
+    // CHECK-NEXT: [[b:%\d+]] = OpLoad %uint %b
+    // CHECK-NEXT: [[any_uint:%\d+]] = OpINotEqual %bool [[b]] %uint_0
+    // CHECK-NEXT: OpStore %result [[any_uint]]
+    uint b;
+    result = any(b);
+
+    // CHECK-NEXT: [[c:%\d+]] = OpLoad %bool %c
+    // CHECK-NEXT: OpStore %result [[c]]
+    bool c;
+    result = any(c);
+
+    // CHECK-NEXT: [[d:%\d+]] = OpLoad %float %d
+    // CHECK-NEXT: [[any_float:%\d+]] = OpFOrdNotEqual %bool [[d]] %float_0
+    // CHECK-NEXT: OpStore %result [[any_float]]
+    float d;
+    result = any(d);
+
+    // CHECK-NEXT: [[e:%\d+]] = OpLoad %int %e
+    // CHECK-NEXT: [[any_int1:%\d+]] = OpINotEqual %bool [[e]] %int_0
+    // CHECK-NEXT: OpStore %result [[any_int1]]
+    int1 e;
+    result = any(e);
+
+    // CHECK-NEXT: [[f:%\d+]] = OpLoad %uint %f
+    // CHECK-NEXT: [[any_uint1:%\d+]] = OpINotEqual %bool [[f]] %uint_0
+    // CHECK-NEXT: OpStore %result [[any_uint1]]
+    uint1 f;
+    result = any(f);
+
+    // CHECK-NEXT: [[g:%\d+]] = OpLoad %bool %g
+    // CHECK-NEXT: OpStore %result [[g]]
+    bool1 g;
+    result = any(g);
+
+    // CHECK-NEXT: [[h:%\d+]] = OpLoad %float %h
+    // CHECK-NEXT: [[any_float1:%\d+]] = OpFOrdNotEqual %bool [[h]] %float_0
+    // CHECK-NEXT: OpStore %result [[any_float1]]
+    float1 h;
+    result = any(h);
+
+    // CHECK-NEXT: [[i:%\d+]] = OpLoad %v4int %i
+    // CHECK-NEXT: [[v4int_to_bool:%\d+]] = OpINotEqual %bool [[i]] [[v4int_0]]
+    // CHECK-NEXT: [[any_int4:%\d+]] = OpAny %bool [[v4int_to_bool]]
+    // CHECK-NEXT: OpStore %result [[any_int4]]
+    int4 i;
+    result = any(i);
+
+    // CHECK-NEXT: [[j:%\d+]] = OpLoad %v4uint %j
+    // CHECK-NEXT: [[v4uint_to_bool:%\d+]] = OpINotEqual %bool [[j]] [[v4uint_0]]
+    // CHECK-NEXT: [[any_uint4:%\d+]] = OpAny %bool [[v4uint_to_bool]]
+    // CHECK-NEXT: OpStore %result [[any_uint4]]
+    uint4 j;
+    result = any(j);
+
+    // CHECK-NEXT: [[k:%\d+]] = OpLoad %v4bool %k
+    // CHECK-NEXT: [[any_bool4:%\d+]] = OpAny %bool [[k]]
+    // CHECK-NEXT: OpStore %result [[any_bool4]]
+    bool4 k;
+    result = any(k);
+
+    // CHECK-NEXT: [[l:%\d+]] = OpLoad %v4float %l
+    // CHECK-NEXT: [[v4float_to_bool:%\d+]] = OpFOrdNotEqual %bool [[l]] [[v4float_0]]
+    // CHECK-NEXT: [[any_float4:%\d+]] = OpAny %bool [[v4float_to_bool]]
+    // CHECK-NEXT: OpStore %result [[any_float4]]
+    float4 l;
+    result = any(l);
+}
+

+ 61 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.asfloat.hlsl

@@ -0,0 +1,61 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'asfloat' function can only operate on int, uint, float,
+// vector of these scalars, and matrix of these scalars.
+
+void main() {
+    float result;
+    float4 result4;
+
+    // CHECK:      [[a:%\d+]] = OpLoad %int %a
+    // CHECK-NEXT: [[a_as_float:%\d+]] = OpBitcast %float [[a]]
+    // CHECK-NEXT: OpStore %result [[a_as_float]]
+    int a;
+    result = asfloat(a);
+
+    // CHECK-NEXT: [[b:%\d+]] = OpLoad %uint %b
+    // CHECK-NEXT: [[b_as_float:%\d+]] = OpBitcast %float [[b]]
+    // CHECK-NEXT: OpStore %result [[b_as_float]]
+    uint b;
+    result = asfloat(b);
+
+    // CHECK-NEXT: [[c:%\d+]] = OpLoad %float %c
+    // CHECK-NEXT: OpStore %result [[c]]
+    float c;
+    result = asfloat(c);
+
+    // CHECK-NEXT: [[d:%\d+]] = OpLoad %int %d
+    // CHECK-NEXT: [[d_as_float:%\d+]] = OpBitcast %float [[d]]
+    // CHECK-NEXT: OpStore %result [[d_as_float]]
+    int1 d;
+    result = asfloat(d);
+
+    // CHECK-NEXT: [[e:%\d+]] = OpLoad %uint %e
+    // CHECK-NEXT: [[e_as_float:%\d+]] = OpBitcast %float [[e]]
+    // CHECK-NEXT: OpStore %result [[e_as_float]]
+    uint1 e;
+    result = asfloat(e);
+
+    // CHECK-NEXT: [[f:%\d+]] = OpLoad %float %f
+    // CHECK-NEXT: OpStore %result [[f]]
+    float1 f;
+    result = asfloat(f);
+
+    // CHECK-NEXT: [[g:%\d+]] = OpLoad %v4int %g
+    // CHECK-NEXT: [[g_as_float:%\d+]] = OpBitcast %v4float [[g]]
+    // CHECK-NEXT: OpStore %result4 [[g_as_float]]
+    int4 g;
+    result4 = asfloat(g);
+
+    // CHECK-NEXT: [[h:%\d+]] = OpLoad %v4uint %h
+    // CHECK-NEXT: [[h_as_float:%\d+]] = OpBitcast %v4float [[h]]
+    // CHECK-NEXT: OpStore %result4 [[h_as_float]]
+    uint4 h;
+    result4 = asfloat(h);
+
+    // CHECK-NEXT: [[i:%\d+]] = OpLoad %v4float %i
+    // CHECK-NEXT: OpStore %result4 [[i]]
+    float4 i;
+    result4 = asfloat(i);
+}

+ 46 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.asint.hlsl

@@ -0,0 +1,46 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'asint' function can only operate on uint, float,
+// vector of these scalars, and matrix of these scalars.
+
+void main() {
+    int result;
+    int4 result4;
+
+    // CHECK:      [[b:%\d+]] = OpLoad %uint %b
+    // CHECK-NEXT: [[b_as_int:%\d+]] = OpBitcast %int [[b]]
+    // CHECK-NEXT: OpStore %result [[b_as_int]]
+    uint b;
+    result = asint(b);
+
+    // CHECK-NEXT: [[c:%\d+]] = OpLoad %float %c
+    // CHECK-NEXT: [[c_as_int:%\d+]] = OpBitcast %int [[c]]
+    // CHECK-NEXT: OpStore %result [[c_as_int]]
+    float c;
+    result = asint(c);
+
+    // CHECK-NEXT: [[e:%\d+]] = OpLoad %uint %e
+    // CHECK-NEXT: [[e_as_int:%\d+]] = OpBitcast %int [[e]]
+    // CHECK-NEXT: OpStore %result [[e_as_int]]
+    uint1 e;
+    result = asint(e);
+
+    // CHECK-NEXT: [[f:%\d+]] = OpLoad %float %f
+    // CHECK-NEXT: [[f_as_int:%\d+]] = OpBitcast %int [[f]]
+    // CHECK-NEXT: OpStore %result [[f_as_int]]
+    float1 f;
+    result = asint(f);
+
+    // CHECK-NEXT: [[h:%\d+]] = OpLoad %v4uint %h
+    // CHECK-NEXT: [[h_as_int:%\d+]] = OpBitcast %v4int [[h]]
+    // CHECK-NEXT: OpStore %result4 [[h_as_int]]
+    uint4 h;
+    result4 = asint(h);
+
+    // CHECK-NEXT: [[i:%\d+]] = OpLoad %v4float %i
+    // CHECK-NEXT: [[i_as_int:%\d+]] = OpBitcast %v4int [[i]]
+    // CHECK-NEXT: OpStore %result4 [[i_as_int]]
+    float4 i;
+    result4 = asint(i);
+}

+ 46 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.asuint.hlsl

@@ -0,0 +1,46 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'asuint' function can only operate on int, float,
+// vector of these scalars, and matrix of these scalars.
+
+void main() {
+    uint result;
+    uint4 result4;
+
+    // CHECK:      [[b:%\d+]] = OpLoad %int %b
+    // CHECK-NEXT: [[b_as_uint:%\d+]] = OpBitcast %uint [[b]]
+    // CHECK-NEXT: OpStore %result [[b_as_uint]]
+    int b;
+    result = asuint(b);
+
+    // CHECK-NEXT: [[c:%\d+]] = OpLoad %float %c
+    // CHECK-NEXT: [[c_as_uint:%\d+]] = OpBitcast %uint [[c]]
+    // CHECK-NEXT: OpStore %result [[c_as_uint]]
+    float c;
+    result = asuint(c);
+
+    // CHECK-NEXT: [[e:%\d+]] = OpLoad %int %e
+    // CHECK-NEXT: [[e_as_uint:%\d+]] = OpBitcast %uint [[e]]
+    // CHECK-NEXT: OpStore %result [[e_as_uint]]
+    int1 e;
+    result = asuint(e);
+
+    // CHECK-NEXT: [[f:%\d+]] = OpLoad %float %f
+    // CHECK-NEXT: [[f_as_uint:%\d+]] = OpBitcast %uint [[f]]
+    // CHECK-NEXT: OpStore %result [[f_as_uint]]
+    float1 f;
+    result = asuint(f);
+
+    // CHECK-NEXT: [[h:%\d+]] = OpLoad %v4int %h
+    // CHECK-NEXT: [[h_as_uint:%\d+]] = OpBitcast %v4uint [[h]]
+    // CHECK-NEXT: OpStore %result4 [[h_as_uint]]
+    int4 h;
+    result4 = asuint(h);
+
+    // CHECK-NEXT: [[i:%\d+]] = OpLoad %v4float %i
+    // CHECK-NEXT: [[i_as_uint:%\d+]] = OpBitcast %v4uint [[i]]
+    // CHECK-NEXT: OpStore %result4 [[i_as_uint]]
+    float4 i;
+    result4 = asuint(i);
+}

+ 6 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -173,6 +173,12 @@ TEST_F(FileTest, ControlFlowConditionalOp) { runFileTest("cf.cond-op.hlsl"); }
 // For function calls
 TEST_F(FileTest, FunctionCall) { runFileTest("fn.call.hlsl"); }
 
+// For intrinsic functions
 TEST_F(FileTest, IntrinsicsDot) { runFileTest("intrinsics.dot.hlsl"); }
+TEST_F(FileTest, IntrinsicsAll) { runFileTest("intrinsics.all.hlsl"); }
+TEST_F(FileTest, IntrinsicsAny) { runFileTest("intrinsics.any.hlsl"); }
+TEST_F(FileTest, IntrinsicsAsfloat) { runFileTest("intrinsics.asfloat.hlsl"); }
+TEST_F(FileTest, IntrinsicsAsint) { runFileTest("intrinsics.asint.hlsl"); }
+TEST_F(FileTest, IntrinsicsAsuint) { runFileTest("intrinsics.asuint.hlsl"); }
 
 } // namespace