Browse Source

[spirv] Translation of more intrinsic HLSL functions (#560)

* cross
* min
* max
* pow
* reflect
* step
Ehsan 8 years ago
parent
commit
4aae84deef

+ 47 - 13
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -2442,23 +2442,32 @@ uint32_t SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
   assert(hlsl::IsIntrinsicOp(callee) &&
   assert(hlsl::IsIntrinsicOp(callee) &&
          "doIntrinsicCallExpr was called for a non-intrinsic function.");
          "doIntrinsicCallExpr was called for a non-intrinsic function.");
 
 
-  const bool isFloatArg =
-      isFloatOrVecMatOfFloatType(callExpr->getArg(0)->getType());
+  const bool isFloatType = isFloatOrVecMatOfFloatType(callExpr->getType());
+  const bool isSintType = isSintOrVecMatOfSintType(callExpr->getType());
   GLSLstd450 glslOpcode = GLSLstd450Bad;
   GLSLstd450 glslOpcode = GLSLstd450Bad;
-  bool actOnEachVecInMat = false;
 
 
 #define INTRINSIC_OP_CASE(intrinsicOp, glslOp, doEachVec)                      \
 #define INTRINSIC_OP_CASE(intrinsicOp, glslOp, doEachVec)                      \
   case hlsl::IntrinsicOp::IOP_##intrinsicOp: {                                 \
   case hlsl::IntrinsicOp::IOP_##intrinsicOp: {                                 \
     glslOpcode = GLSLstd450::GLSLstd450##glslOp;                               \
     glslOpcode = GLSLstd450::GLSLstd450##glslOp;                               \
-    actOnEachVecInMat = doEachVec;                                             \
+    return processIntrinsicUsingGLSLInst(callExpr, glslOpcode, doEachVec);     \
   } break
   } break
 
 
 #define INTRINSIC_OP_CASE_INT_FLOAT(intrinsicOp, glslIntOp, glslFloatOp,       \
 #define INTRINSIC_OP_CASE_INT_FLOAT(intrinsicOp, glslIntOp, glslFloatOp,       \
                                     doEachVec)                                 \
                                     doEachVec)                                 \
   case hlsl::IntrinsicOp::IOP_##intrinsicOp: {                                 \
   case hlsl::IntrinsicOp::IOP_##intrinsicOp: {                                 \
-    glslOpcode = isFloatArg ? GLSLstd450::GLSLstd450##glslFloatOp              \
-                            : GLSLstd450::GLSLstd450##glslIntOp;               \
-    actOnEachVecInMat = doEachVec;                                             \
+    glslOpcode = isFloatType ? GLSLstd450::GLSLstd450##glslFloatOp             \
+                             : GLSLstd450::GLSLstd450##glslIntOp;              \
+    return processIntrinsicUsingGLSLInst(callExpr, glslOpcode, doEachVec);     \
+  } break
+
+#define INTRINSIC_OP_CASE_SINT_UINT_FLOAT(intrinsicOp, glslSintOp, glslUintOp, \
+                                          glslFloatOp, doEachVec)              \
+  case hlsl::IntrinsicOp::IOP_##intrinsicOp: {                                 \
+    glslOpcode = isFloatType                                                   \
+                     ? GLSLstd450::GLSLstd450##glslFloatOp                     \
+                     : isSintType ? GLSLstd450::GLSLstd450##glslSintOp         \
+                                  : GLSLstd450::GLSLstd450##glslUintOp;        \
+    return processIntrinsicUsingGLSLInst(callExpr, glslOpcode, doEachVec);     \
   } break
   } break
 
 
   // Figure out which intrinsic function to translate.
   // Figure out which intrinsic function to translate.
@@ -2479,7 +2488,7 @@ uint32_t SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
   case hlsl::IntrinsicOp::IOP_asuint:
   case hlsl::IntrinsicOp::IOP_asuint:
     return processIntrinsicAsType(callExpr);
     return processIntrinsicAsType(callExpr);
   case hlsl::IntrinsicOp::IOP_sign: {
   case hlsl::IntrinsicOp::IOP_sign: {
-    if (isFloatArg)
+    if (isFloatOrVecMatOfFloatType(callExpr->getArg(0)->getType()))
       return processIntrinsicFloatSign(callExpr);
       return processIntrinsicFloatSign(callExpr);
     else
     else
       return processIntrinsicUsingGLSLInst(callExpr,
       return processIntrinsicUsingGLSLInst(callExpr,
@@ -2494,6 +2503,7 @@ uint32_t SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
     INTRINSIC_OP_CASE(ceil, Ceil, true);
     INTRINSIC_OP_CASE(ceil, Ceil, true);
     INTRINSIC_OP_CASE(cos, Cos, true);
     INTRINSIC_OP_CASE(cos, Cos, true);
     INTRINSIC_OP_CASE(cosh, Cosh, true);
     INTRINSIC_OP_CASE(cosh, Cosh, true);
+    INTRINSIC_OP_CASE(cross, Cross, false);
     INTRINSIC_OP_CASE(degrees, Degrees, true);
     INTRINSIC_OP_CASE(degrees, Degrees, true);
     INTRINSIC_OP_CASE(radians, Radians, true);
     INTRINSIC_OP_CASE(radians, Radians, true);
     INTRINSIC_OP_CASE(determinant, Determinant, false);
     INTRINSIC_OP_CASE(determinant, Determinant, false);
@@ -2503,8 +2513,15 @@ uint32_t SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
     INTRINSIC_OP_CASE(length, Length, false);
     INTRINSIC_OP_CASE(length, Length, false);
     INTRINSIC_OP_CASE(log, Log, true);
     INTRINSIC_OP_CASE(log, Log, true);
     INTRINSIC_OP_CASE(log2, Log2, true);
     INTRINSIC_OP_CASE(log2, Log2, true);
+    INTRINSIC_OP_CASE_SINT_UINT_FLOAT(max, SMax, UMax, FMax, true);
+    INTRINSIC_OP_CASE(umax, UMax, true);
+    INTRINSIC_OP_CASE_SINT_UINT_FLOAT(min, SMin, UMin, FMin, true);
+    INTRINSIC_OP_CASE(umin, UMin, true);
     INTRINSIC_OP_CASE(normalize, Normalize, false);
     INTRINSIC_OP_CASE(normalize, Normalize, false);
+    INTRINSIC_OP_CASE(pow, Pow, true);
+    INTRINSIC_OP_CASE(reflect, Reflect, false);
     INTRINSIC_OP_CASE(rsqrt, InverseSqrt, true);
     INTRINSIC_OP_CASE(rsqrt, InverseSqrt, true);
+    INTRINSIC_OP_CASE(step, Step, true);
     INTRINSIC_OP_CASE(sin, Sin, true);
     INTRINSIC_OP_CASE(sin, Sin, true);
     INTRINSIC_OP_CASE(sinh, Sinh, true);
     INTRINSIC_OP_CASE(sinh, Sinh, true);
     INTRINSIC_OP_CASE(tan, Tan, true);
     INTRINSIC_OP_CASE(tan, Tan, true);
@@ -2520,7 +2537,7 @@ uint32_t SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
 #undef INTRINSIC_OP_CASE
 #undef INTRINSIC_OP_CASE
 #undef INTRINSIC_OP_CASE_INT_FLOAT
 #undef INTRINSIC_OP_CASE_INT_FLOAT
 
 
-  return processIntrinsicUsingGLSLInst(callExpr, glslOpcode, actOnEachVecInMat);
+  return 0;
 }
 }
 
 
 uint32_t SPIRVEmitter::processIntrinsicMul(const CallExpr *callExpr) {
 uint32_t SPIRVEmitter::processIntrinsicMul(const CallExpr *callExpr) {
@@ -2860,10 +2877,8 @@ uint32_t SPIRVEmitter::processIntrinsicUsingGLSLInst(
     const CallExpr *callExpr, GLSLstd450 opcode, bool actPerRowForMatrices) {
     const CallExpr *callExpr, GLSLstd450 opcode, bool actPerRowForMatrices) {
   // Import the GLSL.std.450 extended instruction set.
   // Import the GLSL.std.450 extended instruction set.
   const uint32_t glslInstSetId = theBuilder.getGLSLExtInstSet();
   const uint32_t glslInstSetId = theBuilder.getGLSLExtInstSet();
-
+  const uint32_t returnType = typeTranslator.translateType(callExpr->getType());
   if (callExpr->getNumArgs() == 1u) {
   if (callExpr->getNumArgs() == 1u) {
-    const uint32_t returnType =
-        typeTranslator.translateType(callExpr->getType());
     const Expr *arg = callExpr->getArg(0);
     const Expr *arg = callExpr->getArg(0);
     const uint32_t argId = doExpr(arg);
     const uint32_t argId = doExpr(arg);
 
 
@@ -2878,8 +2893,27 @@ uint32_t SPIRVEmitter::processIntrinsicUsingGLSLInst(
       };
       };
       return processEachVectorInMatrix(arg, argId, actOnEachVec);
       return processEachVectorInMatrix(arg, argId, actOnEachVec);
     }
     }
-
     return theBuilder.createExtInst(returnType, glslInstSetId, opcode, {argId});
     return theBuilder.createExtInst(returnType, glslInstSetId, opcode, {argId});
+  } else if (callExpr->getNumArgs() == 2u) {
+    const Expr *arg0 = callExpr->getArg(0);
+    const Expr *arg1 = callExpr->getArg(1);
+    const uint32_t arg0Id = doExpr(arg0);
+    const uint32_t arg1Id = doExpr(arg1);
+    // If the instruction does not operate on matrices, we can perform the
+    // instruction on each vector of the matrix.
+    if (actPerRowForMatrices &&
+        TypeTranslator::isSpirvAcceptableMatrixType(arg0->getType())) {
+      const auto actOnEachVec = [this, glslInstSetId, opcode, arg1Id](
+          uint32_t index, uint32_t vecType, uint32_t arg0RowId) {
+        const uint32_t arg1RowId =
+            theBuilder.createCompositeExtract(vecType, arg1Id, {index});
+        return theBuilder.createExtInst(vecType, glslInstSetId, opcode,
+                                        {arg0RowId, arg1RowId});
+      };
+      return processEachVectorInMatrix(arg0, arg0Id, actOnEachVec);
+    }
+    return theBuilder.createExtInst(returnType, glslInstSetId, opcode,
+                                    {arg0Id, arg1Id});
   }
   }
 
 
   emitError("Unsupported intrinsic function %0.")
   emitError("Unsupported intrinsic function %0.")

+ 15 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.cross.hlsl

@@ -0,0 +1,15 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// According to HLSL reference:
+// The 'cross' function can only operate on float3 vectors.
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float3 a,b,c;
+
+// CHECK:      [[a:%\d+]] = OpLoad %v3float %a
+// CHECK-NEXT: [[b:%\d+]] = OpLoad %v3float %b
+// CHECK-NEXT: [[c:%\d+]] = OpExtInst %v3float [[glsl]] Cross [[a]] [[b]]
+  c = cross(a,b);
+}

+ 57 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.max.hlsl

@@ -0,0 +1,57 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float result;
+  float2 result2;
+  float3 result3;
+  float4 result4;
+  float2x3 result2x3;
+  int3 iresult3;
+  uint3 uresult3;
+
+// CHECK: {{%\d+}} = OpExtInst %v3int [[glsl]] SMax {{%\d+}} {{%\d+}}
+  int3 i1,i2;
+  iresult3 = max(i1,i2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3uint [[glsl]] UMax {{%\d+}} {{%\d+}}
+  uint3 j1,j2;
+  uresult3 = max(j1,j2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float a1,a2;
+  result = max(a1,a2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float1 b1,b2;
+  result = max(b1,b2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float3 c1,c2;
+  result3 = max(c1,c2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float1x1 d1,d2;
+  result = max(d1,d2);
+
+// CHECK: {{%\d+}} = OpExtInst %v2float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float1x2 e1,e2;
+  result2 = max(e1,e2);
+
+// CHECK: {{%\d+}} = OpExtInst %v4float [[glsl]] FMax {{%\d+}} {{%\d+}}
+  float4x1 f1,f2;
+  result4 = max(f1,f2);
+
+// CHECK:      [[g1:%\d+]] = OpLoad %mat2v3float %g1
+// CHECK-NEXT: [[g2:%\d+]] = OpLoad %mat2v3float %g2
+// CHECK-NEXT: [[g1_row0:%\d+]] = OpCompositeExtract %v3float [[g1]] 0
+// CHECK-NEXT: [[g2_row0:%\d+]] = OpCompositeExtract %v3float [[g2]] 0
+// CHECK-NEXT: [[result_row0:%\d+]] = OpExtInst %v3float [[glsl]] FMax [[g1_row0]] [[g2_row0]]
+// CHECK-NEXT: [[g1_row1:%\d+]] = OpCompositeExtract %v3float [[g1]] 1
+// CHECK-NEXT: [[g2_row1:%\d+]] = OpCompositeExtract %v3float [[g2]] 1
+// CHECK-NEXT: [[result_row1:%\d+]] = OpExtInst %v3float [[glsl]] FMax [[g1_row1]] [[g2_row1]]
+// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %mat2v3float [[result_row0]] [[result_row1]]
+  float2x3 g1,g2;
+  result2x3 = max(g1,g2);
+}

+ 57 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.min.hlsl

@@ -0,0 +1,57 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float result;
+  float2 result2;
+  float3 result3;
+  float4 result4;
+  float2x3 result2x3;
+  int3 iresult3;
+  uint3 uresult3;
+
+// CHECK: {{%\d+}} = OpExtInst %v3int [[glsl]] SMin {{%\d+}} {{%\d+}}
+  int3 i1,i2;
+  iresult3 = min(i1,i2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3uint [[glsl]] UMin {{%\d+}} {{%\d+}}
+  uint3 j1,j2;
+  uresult3 = min(j1,j2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float a1,a2;
+  result = min(a1,a2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float1 b1,b2;
+  result = min(b1,b2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float3 c1,c2;
+  result3 = min(c1,c2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float1x1 d1,d2;
+  result = min(d1,d2);
+
+// CHECK: {{%\d+}} = OpExtInst %v2float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float1x2 e1,e2;
+  result2 = min(e1,e2);
+
+// CHECK: {{%\d+}} = OpExtInst %v4float [[glsl]] FMin {{%\d+}} {{%\d+}}
+  float4x1 f1,f2;
+  result4 = min(f1,f2);
+
+// CHECK:      [[g1:%\d+]] = OpLoad %mat2v3float %g1
+// CHECK-NEXT: [[g2:%\d+]] = OpLoad %mat2v3float %g2
+// CHECK-NEXT: [[g1_row0:%\d+]] = OpCompositeExtract %v3float [[g1]] 0
+// CHECK-NEXT: [[g2_row0:%\d+]] = OpCompositeExtract %v3float [[g2]] 0
+// CHECK-NEXT: [[result_row0:%\d+]] = OpExtInst %v3float [[glsl]] FMin [[g1_row0]] [[g2_row0]]
+// CHECK-NEXT: [[g1_row1:%\d+]] = OpCompositeExtract %v3float [[g1]] 1
+// CHECK-NEXT: [[g2_row1:%\d+]] = OpCompositeExtract %v3float [[g2]] 1
+// CHECK-NEXT: [[result_row1:%\d+]] = OpExtInst %v3float [[glsl]] FMin [[g1_row1]] [[g2_row1]]
+// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %mat2v3float [[result_row0]] [[result_row1]]
+  float2x3 g1,g2;
+  result2x3 = min(g1,g2);
+}

+ 47 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.pow.hlsl

@@ -0,0 +1,47 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float result;
+  float2 result2;
+  float3 result3;
+  float4 result4;
+  float2x3 result2x3;
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float a1,a2;
+  result = pow(a1,a2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float1 b1,b2;
+  result = pow(b1,b2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float3 c1,c2;
+  result3 = pow(c1,c2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float1x1 d1,d2;
+  result = pow(d1,d2);
+
+// CHECK: {{%\d+}} = OpExtInst %v2float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float1x2 e1,e2;
+  result2 = pow(e1,e2);
+
+// CHECK: {{%\d+}} = OpExtInst %v4float [[glsl]] Pow {{%\d+}} {{%\d+}}
+  float4x1 f1,f2;
+  result4 = pow(f1,f2);
+
+// CHECK:      [[g1:%\d+]] = OpLoad %mat2v3float %g1
+// CHECK-NEXT: [[g2:%\d+]] = OpLoad %mat2v3float %g2
+// CHECK-NEXT: [[g1_row0:%\d+]] = OpCompositeExtract %v3float [[g1]] 0
+// CHECK-NEXT: [[g2_row0:%\d+]] = OpCompositeExtract %v3float [[g2]] 0
+// CHECK-NEXT: [[result_row0:%\d+]] = OpExtInst %v3float [[glsl]] Pow [[g1_row0]] [[g2_row0]]
+// CHECK-NEXT: [[g1_row1:%\d+]] = OpCompositeExtract %v3float [[g1]] 1
+// CHECK-NEXT: [[g2_row1:%\d+]] = OpCompositeExtract %v3float [[g2]] 1
+// CHECK-NEXT: [[result_row1:%\d+]] = OpExtInst %v3float [[glsl]] Pow [[g1_row1]] [[g2_row1]]
+// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %mat2v3float [[result_row0]] [[result_row1]]
+  float2x3 g1,g2;
+  result2x3 = pow(g1,g2);
+}

+ 12 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.reflect.hlsl

@@ -0,0 +1,12 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// HLSL reflect() only operates on vectors of floats.
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float4 a1,a2,result;
+
+// CHECK: {{%\d+}} = OpExtInst %v4float [[glsl]] Reflect {{%\d+}} {{%\d+}}
+  result = reflect(a1,a2);
+}

+ 47 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.step.hlsl

@@ -0,0 +1,47 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK:      [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
+
+void main() {
+  float result;
+  float2 result2;
+  float3 result3;
+  float4 result4;
+  float2x3 result2x3;
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float a1,a2;
+  result = step(a1,a2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float1 b1,b2;
+  result = step(b1,b2);
+
+// CHECK: {{%\d+}} = OpExtInst %v3float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float3 c1,c2;
+  result3 = step(c1,c2);
+
+// CHECK: {{%\d+}} = OpExtInst %float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float1x1 d1,d2;
+  result = step(d1,d2);
+
+// CHECK: {{%\d+}} = OpExtInst %v2float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float1x2 e1,e2;
+  result2 = step(e1,e2);
+
+// CHECK: {{%\d+}} = OpExtInst %v4float [[glsl]] Step {{%\d+}} {{%\d+}}
+  float4x1 f1,f2;
+  result4 = step(f1,f2);
+
+// CHECK:      [[g1:%\d+]] = OpLoad %mat2v3float %g1
+// CHECK-NEXT: [[g2:%\d+]] = OpLoad %mat2v3float %g2
+// CHECK-NEXT: [[g1_row0:%\d+]] = OpCompositeExtract %v3float [[g1]] 0
+// CHECK-NEXT: [[g2_row0:%\d+]] = OpCompositeExtract %v3float [[g2]] 0
+// CHECK-NEXT: [[result_row0:%\d+]] = OpExtInst %v3float [[glsl]] Step [[g1_row0]] [[g2_row0]]
+// CHECK-NEXT: [[g1_row1:%\d+]] = OpCompositeExtract %v3float [[g1]] 1
+// CHECK-NEXT: [[g2_row1:%\d+]] = OpCompositeExtract %v3float [[g2]] 1
+// CHECK-NEXT: [[result_row1:%\d+]] = OpExtInst %v3float [[glsl]] Step [[g1_row1]] [[g2_row1]]
+// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %mat2v3float [[result_row0]] [[result_row1]]
+  float2x3 g1,g2;
+  result2x3 = step(g1,g2);
+}

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

@@ -281,6 +281,7 @@ TEST_F(FileTest, IntrinsicsAsint) { runFileTest("intrinsics.asint.hlsl"); }
 TEST_F(FileTest, IntrinsicsAsuint) { runFileTest("intrinsics.asuint.hlsl"); }
 TEST_F(FileTest, IntrinsicsAsuint) { runFileTest("intrinsics.asuint.hlsl"); }
 TEST_F(FileTest, IntrinsicsRound) { runFileTest("intrinsics.round.hlsl"); }
 TEST_F(FileTest, IntrinsicsRound) { runFileTest("intrinsics.round.hlsl"); }
 TEST_F(FileTest, IntrinsicsAbs) { runFileTest("intrinsics.abs.hlsl"); }
 TEST_F(FileTest, IntrinsicsAbs) { runFileTest("intrinsics.abs.hlsl"); }
+TEST_F(FileTest, IntrinsicsCross) { runFileTest("intrinsics.cross.hlsl"); }
 TEST_F(FileTest, IntrinsicsCeil) { runFileTest("intrinsics.ceil.hlsl"); }
 TEST_F(FileTest, IntrinsicsCeil) { runFileTest("intrinsics.ceil.hlsl"); }
 TEST_F(FileTest, IntrinsicsDegrees) { runFileTest("intrinsics.degrees.hlsl"); }
 TEST_F(FileTest, IntrinsicsDegrees) { runFileTest("intrinsics.degrees.hlsl"); }
 TEST_F(FileTest, IntrinsicsRadians) { runFileTest("intrinsics.radians.hlsl"); }
 TEST_F(FileTest, IntrinsicsRadians) { runFileTest("intrinsics.radians.hlsl"); }
@@ -293,14 +294,19 @@ TEST_F(FileTest, IntrinsicsFloor) { runFileTest("intrinsics.floor.hlsl"); }
 TEST_F(FileTest, IntrinsicsLength) { runFileTest("intrinsics.length.hlsl"); }
 TEST_F(FileTest, IntrinsicsLength) { runFileTest("intrinsics.length.hlsl"); }
 TEST_F(FileTest, IntrinsicsLog) { runFileTest("intrinsics.log.hlsl"); }
 TEST_F(FileTest, IntrinsicsLog) { runFileTest("intrinsics.log.hlsl"); }
 TEST_F(FileTest, IntrinsicsLog2) { runFileTest("intrinsics.log2.hlsl"); }
 TEST_F(FileTest, IntrinsicsLog2) { runFileTest("intrinsics.log2.hlsl"); }
+TEST_F(FileTest, IntrinsicsMin) { runFileTest("intrinsics.min.hlsl"); }
+TEST_F(FileTest, IntrinsicsMax) { runFileTest("intrinsics.max.hlsl"); }
 TEST_F(FileTest, IntrinsicsNormalize) {
 TEST_F(FileTest, IntrinsicsNormalize) {
   runFileTest("intrinsics.normalize.hlsl");
   runFileTest("intrinsics.normalize.hlsl");
 }
 }
+TEST_F(FileTest, IntrinsicsPow) { runFileTest("intrinsics.pow.hlsl"); }
 TEST_F(FileTest, IntrinsicsRsqrt) { runFileTest("intrinsics.rsqrt.hlsl"); }
 TEST_F(FileTest, IntrinsicsRsqrt) { runFileTest("intrinsics.rsqrt.hlsl"); }
 TEST_F(FileTest, IntrinsicsFloatSign) {
 TEST_F(FileTest, IntrinsicsFloatSign) {
   runFileTest("intrinsics.floatsign.hlsl");
   runFileTest("intrinsics.floatsign.hlsl");
 }
 }
 TEST_F(FileTest, IntrinsicsIntSign) { runFileTest("intrinsics.intsign.hlsl"); }
 TEST_F(FileTest, IntrinsicsIntSign) { runFileTest("intrinsics.intsign.hlsl"); }
+TEST_F(FileTest, IntrinsicsReflect) { runFileTest("intrinsics.reflect.hlsl"); }
+TEST_F(FileTest, IntrinsicsStep) { runFileTest("intrinsics.step.hlsl"); }
 TEST_F(FileTest, IntrinsicsSqrt) { runFileTest("intrinsics.sqrt.hlsl"); }
 TEST_F(FileTest, IntrinsicsSqrt) { runFileTest("intrinsics.sqrt.hlsl"); }
 TEST_F(FileTest, IntrinsicsTrunc) { runFileTest("intrinsics.trunc.hlsl"); }
 TEST_F(FileTest, IntrinsicsTrunc) { runFileTest("intrinsics.trunc.hlsl"); }