From 923ef7af304f2f118b0aee153bd50e054ebc50c9 Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:07:06 -0400 Subject: 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 --- source/slang/slang-diagnostic-defs.h | 4 ++++ source/slang/slang-emit.cpp | 2 +- source/slang/slang-ir-lower-bit-cast.cpp | 16 +++++++++++++++- source/slang/slang-ir-lower-bit-cast.h | 3 ++- source/slang/slang-ir-lower-reinterpret.cpp | 8 ++++++++ .../bit-cast/narrowing-bit-cast-error.slang | 12 ++++++++++++ tests/language-feature/bit-cast/struct-bit-cast.slang | 6 +----- .../bit-cast/widening-bit-cast-error.slang | 12 ++++++++++++ .../reinterpret/narrowing-reinterpret-warning.slang | 12 ++++++++++++ .../reinterpret/widening-reinterpret-warning.slang | 12 ++++++++++++ 10 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 tests/language-feature/bit-cast/narrowing-bit-cast-error.slang create mode 100644 tests/language-feature/bit-cast/widening-bit-cast-error.slang create mode 100644 tests/language-feature/reinterpret/narrowing-reinterpret-warning.slang create mode 100644 tests/language-feature/reinterpret/widening-reinterpret-warning.slang 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 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(fromType) != nullptr && as(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 in; +uniform RWStructuredBuffer out; + +//CHECK: error 41202{{.*}}8{{.*}}4 + +[numthreads(4, 1, 1)] +[shader("compute")] +void computeMain() { + out[0] = bit_cast(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(s).y; // 0. - Larger l = {1, 2}; - int v1 = bit_cast(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 in; +uniform RWStructuredBuffer out; + +//CHECK: error 41202{{.*}}4{{.*}}8 + +[numthreads(4, 1, 1)] +[shader("compute")] +void computeMain() { + out[0] = bit_cast(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 in; +uniform RWStructuredBuffer out; + +// CHECK: warning 41203{{.*}}8{{.*}}4 + +[numthreads(4, 1, 1)] +[shader("compute")] +void computeMain() { + out[0] = reinterpret(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 in; +uniform RWStructuredBuffer out; + +//CHECK: warning 41203{{.*}}4{{.*}}8 + +[numthreads(4, 1, 1)] +[shader("compute")] +void computeMain() { + out[0] = reinterpret(in[0]); +} \ No newline at end of file -- cgit v1.2.3