Browse Source

[spirv] Emit error for atomics operations on floats (#1382)

Lei Zhang 7 năm trước cách đây
mục cha
commit
eaff1735d0

+ 7 - 0
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -6663,6 +6663,13 @@ SPIRVEmitter::processIntrinsicInterlockedMethod(const CallExpr *expr,
   const uint32_t scope = theBuilder.getConstantUint32(1); // Device
   const uint32_t scope = theBuilder.getConstantUint32(1); // Device
   const auto *dest = expr->getArg(0);
   const auto *dest = expr->getArg(0);
   const auto baseType = dest->getType();
   const auto baseType = dest->getType();
+
+  if (!baseType->isIntegerType()) {
+    emitError("can only perform atomic operations on scalar integer values",
+              dest->getLocStart());
+    return 0;
+  }
+
   const uint32_t baseTypeId = typeTranslator.translateType(baseType);
   const uint32_t baseTypeId = typeTranslator.translateType(baseType);
 
 
   const auto doArg = [baseType, this](const CallExpr *callExpr,
   const auto doArg = [baseType, this](const CallExpr *callExpr,

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

@@ -0,0 +1,19 @@
+// Run: %dxc -T cs_6_0 -E main
+
+groupshared float MyFloat;
+RWBuffer<float> MyBuffer;
+
+typedef int MyIntegerType;
+RWStructuredBuffer<MyIntegerType> MySBuffer;
+
+[numthreads(1, 1, 1)]
+void main()
+{
+  InterlockedAdd(MyFloat, 1);
+  InterlockedCompareStore(MyBuffer[0], MySBuffer[0], MySBuffer[1]);
+  InterlockedXor(MySBuffer[2], 5);
+}
+
+// CHECK:     :12:18: error: can only perform atomic operations on scalar integer values
+// CHECK:     :13:27: error: can only perform atomic operations on scalar integer values
+// CHECK-NOT:         error: can only perform atomic operations on scalar integer values

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

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