summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-04-22 10:07:06 -0400
committerGitHub <noreply@github.com>2024-04-22 10:07:06 -0400
commit923ef7af304f2f118b0aee153bd50e054ebc50c9 (patch)
tree9cb2b161bf88040fb36239d476d39b7cda8933d1
parentc5b855d77f6cdcc1ecb5c24de98f28347700e3c8 (diff)
bit_cast & reinterpret warning if src->dst type not equally sized. (#3988)
* bit_cast & reinterpret warning if src->dst type not equally sized. bit_cast & reinterpret warning if src->dst type not equally sized. --------- Co-authored-by: Yong He <yonghe@outlook.com>
-rw-r--r--source/slang/slang-diagnostic-defs.h4
-rw-r--r--source/slang/slang-emit.cpp2
-rw-r--r--source/slang/slang-ir-lower-bit-cast.cpp16
-rw-r--r--source/slang/slang-ir-lower-bit-cast.h3
-rw-r--r--source/slang/slang-ir-lower-reinterpret.cpp8
-rw-r--r--tests/language-feature/bit-cast/narrowing-bit-cast-error.slang12
-rw-r--r--tests/language-feature/bit-cast/struct-bit-cast.slang6
-rw-r--r--tests/language-feature/bit-cast/widening-bit-cast-error.slang12
-rw-r--r--tests/language-feature/reinterpret/narrowing-reinterpret-warning.slang12
-rw-r--r--tests/language-feature/reinterpret/widening-reinterpret-warning.slang12
10 files changed, 79 insertions, 8 deletions
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index c2e76dffe..0c5d0f10c 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -744,6 +744,10 @@ DIAGNOSTIC(45001, Error, unresolvedSymbol, "unresolved external symbol '$0'.")
DIAGNOSTIC(41201, Warning, expectDynamicUniformArgument, "argument for '$0' might not be a dynamic uniform, use `asDynamicUniform()` to silence this warning.")
DIAGNOSTIC(41201, Warning, expectDynamicUniformValue, "value stored at this location must be dynamic uniform, use `asDynamicUniform()` to silence this warning.")
+
+DIAGNOSTIC(41202, Error, notEqualBitCastSize, "invalid to bit_cast differently sized types: '$0' with size '$1' casted into '$2' with size '$3'")
+DIAGNOSTIC(41203, Warning, notEqualReinterpretCastSize, "reinterpret<> into not equally sized types: '$0' with size '$1' casted into '$2' with size '$3'")
+
//
// 5xxxx - Target code generation.
//
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index b7227a4f0..f492167a2 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -965,7 +965,7 @@ Result linkAndOptimizeIR(
// Lower all bit_cast operations on complex types into leaf-level
// bit_cast on basic types.
- lowerBitCast(targetProgram, irModule);
+ lowerBitCast(targetProgram, irModule, sink);
bool emitSpirvDirectly = targetProgram->getOptionSet().shouldEmitSPIRVDirectly();
diff --git a/source/slang/slang-ir-lower-bit-cast.cpp b/source/slang/slang-ir-lower-bit-cast.cpp
index 7a9f605d2..33516f54a 100644
--- a/source/slang/slang-ir-lower-bit-cast.cpp
+++ b/source/slang/slang-ir-lower-bit-cast.cpp
@@ -12,6 +12,7 @@ struct BitCastLoweringContext
TargetProgram* targetProgram;
IRModule* module;
OrderedHashSet<IRInst*> workList;
+ DiagnosticSink* sink;
void addToWorkList(IRInst* inst)
{
@@ -212,8 +213,16 @@ struct BitCastLoweringContext
auto operand = inst->getOperand(0);
auto fromType = operand->getDataType();
auto toType = inst->getDataType();
+
+ IRSizeAndAlignment toTypeSize;
+ getNaturalSizeAndAlignment(targetProgram->getOptionSet(), toType, &toTypeSize);
+ IRSizeAndAlignment fromTypeSize;
+ getNaturalSizeAndAlignment(targetProgram->getOptionSet(), fromType, &fromTypeSize);
+
if (as<IRBasicType>(fromType) != nullptr && as<IRBasicType>(toType) != nullptr)
{
+ if (fromTypeSize.size != toTypeSize.size)
+ sink->diagnose(inst->sourceLoc, Diagnostics::notEqualBitCastSize, fromType, fromTypeSize.size, toType, toTypeSize.size);
// Both fromType and toType are basic types, no processing needed.
return;
}
@@ -238,6 +247,10 @@ struct BitCastLoweringContext
{
return;
}
+
+ if (fromTypeSize.size != toTypeSize.size)
+ sink->diagnose(inst->sourceLoc, Diagnostics::notEqualBitCastSize, fromType, fromTypeSize.size, toType, toTypeSize.size);
+
// Enumerate all fields in to-type and obtain its value from operand object.
IRBuilder builder(module);
builder.setInsertBefore(inst);
@@ -247,11 +260,12 @@ struct BitCastLoweringContext
}
};
-void lowerBitCast(TargetProgram* targetProgram, IRModule* module)
+void lowerBitCast(TargetProgram* targetProgram, IRModule* module, DiagnosticSink* sink)
{
BitCastLoweringContext context;
context.module = module;
context.targetProgram = targetProgram;
+ context.sink = sink;
context.processModule();
}
diff --git a/source/slang/slang-ir-lower-bit-cast.h b/source/slang/slang-ir-lower-bit-cast.h
index cb80d0dab..8c2547515 100644
--- a/source/slang/slang-ir-lower-bit-cast.h
+++ b/source/slang/slang-ir-lower-bit-cast.h
@@ -8,8 +8,9 @@ namespace Slang
{
struct IRModule;
+class DiagnosticSink;
class TargetProgram;
-void lowerBitCast(TargetProgram* targetReq, IRModule* module);
+void lowerBitCast(TargetProgram* targetReq, IRModule* module, DiagnosticSink* sink);
}
diff --git a/source/slang/slang-ir-lower-reinterpret.cpp b/source/slang/slang-ir-lower-reinterpret.cpp
index afc710539..34d4b77d9 100644
--- a/source/slang/slang-ir-lower-reinterpret.cpp
+++ b/source/slang/slang-ir-lower-reinterpret.cpp
@@ -60,15 +60,23 @@ struct ReinterpretLoweringContext
auto fromType = operand->getDataType();
auto toType = inst->getDataType();
SlangInt fromTypeSize = getAnyValueSize(fromType);
+ bool cantPack = false;
if (fromTypeSize < 0)
{
+ cantPack = true;
sink->diagnose(inst->sourceLoc, Slang::Diagnostics::typeCannotBePackedIntoAnyValue, fromType);
}
SlangInt toTypeSize = getAnyValueSize(toType);
if (toTypeSize < 0)
{
+ cantPack = true;
sink->diagnose(inst->sourceLoc, Slang::Diagnostics::typeCannotBePackedIntoAnyValue, toType);
}
+ if (fromTypeSize != toTypeSize
+ && cantPack == false)
+ {
+ sink->diagnose(inst->sourceLoc, Slang::Diagnostics::notEqualReinterpretCastSize, fromType, fromTypeSize, toType, toTypeSize);
+ }
SlangInt anyValueSize = Math::Max(fromTypeSize, toTypeSize);
IRBuilder builder(module);
diff --git a/tests/language-feature/bit-cast/narrowing-bit-cast-error.slang b/tests/language-feature/bit-cast/narrowing-bit-cast-error.slang
new file mode 100644
index 000000000..0591144a9
--- /dev/null
+++ b/tests/language-feature/bit-cast/narrowing-bit-cast-error.slang
@@ -0,0 +1,12 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -stage compute -entry computeMain
+
+uniform StructuredBuffer<uint64_t> in;
+uniform RWStructuredBuffer<uint32_t> out;
+
+//CHECK: error 41202{{.*}}8{{.*}}4
+
+[numthreads(4, 1, 1)]
+[shader("compute")]
+void computeMain() {
+ out[0] = bit_cast<uint32_t, uint64_t>(in[0]);
+} \ No newline at end of file
diff --git a/tests/language-feature/bit-cast/struct-bit-cast.slang b/tests/language-feature/bit-cast/struct-bit-cast.slang
index 5398f36c9..630efb1e0 100644
--- a/tests/language-feature/bit-cast/struct-bit-cast.slang
+++ b/tests/language-feature/bit-cast/struct-bit-cast.slang
@@ -47,11 +47,7 @@ struct Larger
int test1()
{
- Smaller s = {1};
- int v0 = bit_cast<Larger, Smaller>(s).y; // 0.
- Larger l = {1, 2};
- int v1 = bit_cast<Smaller, Larger>(l).s; // 1.
- return v0 + v1;
+ return 1;
}
diff --git a/tests/language-feature/bit-cast/widening-bit-cast-error.slang b/tests/language-feature/bit-cast/widening-bit-cast-error.slang
new file mode 100644
index 000000000..29dc5a4e1
--- /dev/null
+++ b/tests/language-feature/bit-cast/widening-bit-cast-error.slang
@@ -0,0 +1,12 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -stage compute -entry computeMain
+
+uniform StructuredBuffer<uint32_t> in;
+uniform RWStructuredBuffer<uint64_t> out;
+
+//CHECK: error 41202{{.*}}4{{.*}}8
+
+[numthreads(4, 1, 1)]
+[shader("compute")]
+void computeMain() {
+ out[0] = bit_cast<uint64_t, uint32_t>(in[0]);
+} \ No newline at end of file
diff --git a/tests/language-feature/reinterpret/narrowing-reinterpret-warning.slang b/tests/language-feature/reinterpret/narrowing-reinterpret-warning.slang
new file mode 100644
index 000000000..98ed71165
--- /dev/null
+++ b/tests/language-feature/reinterpret/narrowing-reinterpret-warning.slang
@@ -0,0 +1,12 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -stage compute -entry computeMain
+
+uniform StructuredBuffer<uint32_t[2]> in;
+uniform RWStructuredBuffer<uint32_t> out;
+
+// CHECK: warning 41203{{.*}}8{{.*}}4
+
+[numthreads(4, 1, 1)]
+[shader("compute")]
+void computeMain() {
+ out[0] = reinterpret<uint32_t>(in[0]);
+} \ No newline at end of file
diff --git a/tests/language-feature/reinterpret/widening-reinterpret-warning.slang b/tests/language-feature/reinterpret/widening-reinterpret-warning.slang
new file mode 100644
index 000000000..2f643cc3f
--- /dev/null
+++ b/tests/language-feature/reinterpret/widening-reinterpret-warning.slang
@@ -0,0 +1,12 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -stage compute -entry computeMain
+
+uniform StructuredBuffer<uint32_t> in;
+uniform RWStructuredBuffer<uint32_t[2]> out;
+
+//CHECK: warning 41203{{.*}}4{{.*}}8
+
+[numthreads(4, 1, 1)]
+[shader("compute")]
+void computeMain() {
+ out[0] = reinterpret<uint32_t[2]>(in[0]);
+} \ No newline at end of file