Browse Source

[spirv] Error out if static variable is used in interlocked method (#1575)

Ehsan 7 years ago
parent
commit
b2a8cd1ba2

+ 11 - 2
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -6859,8 +6859,17 @@ SPIRVEmitter::processIntrinsicInterlockedMethod(const CallExpr *expr,
       }
     }
   }
-  if (!ptr)
-    ptr = doExpr(dest);
+  if (!ptr) {
+    const auto ptrInfo = doExpr(dest);
+    const auto sc = ptrInfo.getStorageClass();
+    if (sc == spv::StorageClass::Private || sc == spv::StorageClass::Function) {
+      emitError("using static variable or function scope variable in "
+                "interlocked operation is not allowed",
+                dest->getExprLoc());
+      return 0;
+    }
+    ptr = ptrInfo;
+  }
 
   const bool isCompareExchange =
       opcode == hlsl::IntrinsicOp::IOP_InterlockedCompareExchange;

+ 14 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.interlocked-methods.static-error.hlsl

@@ -0,0 +1,14 @@
+// Run: %dxc -T cs_6_0 -E main
+
+static uint g_globalMeshCounter;
+
+[numthreads(1, 1, 1)]
+void main(
+	uint groupIdx : SV_GroupID,
+	uint localIdx : SV_GroupThreadID)
+{
+	uint offset;
+	InterlockedAdd(g_globalMeshCounter, 1, offset);
+}
+
+// CHECK: :11:17: error: using static variable or function scope variable in interlocked operation is not allowed

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

@@ -930,6 +930,9 @@ TEST_F(FileTest, IntrinsicsInterlockedMethodsCS) {
 TEST_F(FileTest, IntrinsicsInterlockedMethodsError) {
   runFileTest("intrinsics.interlocked-methods.error.hlsl", Expect::Failure);
 }
+TEST_F(FileTest, IntrinsicsInterlockedMethodsStaticError) {
+  runFileTest("intrinsics.interlocked-methods.static-error.hlsl", Expect::Failure);
+}
 TEST_F(FileTest, IntrinsicsIsInf) { runFileTest("intrinsics.isinf.hlsl"); }
 TEST_F(FileTest, IntrinsicsIsNan) { runFileTest("intrinsics.isnan.hlsl"); }
 TEST_F(FileTest, IntrinsicsLength) { runFileTest("intrinsics.length.hlsl"); }