From 93a3ba812dd33b10f166f9172bd781e84d938e21 Mon Sep 17 00:00:00 2001 From: venkataram-nv Date: Wed, 31 Jul 2024 11:51:09 -0700 Subject: Warnings target switch intrinsic asm (#4727) * Proper warning generation for target switches and intrinsic asm * Relaxing terminators * Fix compiler warnings * Rectified target switch reachability check * Simplify target switch reachability check * Refactoring variable names * Using getBlocks * Moving ad hoc special case to diagnostics source * Using the LINE directive for testing * Simplifying reliance on target switches * Skipping IR generation for empty target switches --------- Co-authored-by: Yong He --- source/slang/slang-ir-use-uninitialized-values.cpp | 99 +++++++++++----------- 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'source/slang/slang-ir-use-uninitialized-values.cpp') diff --git a/source/slang/slang-ir-use-uninitialized-values.cpp b/source/slang/slang-ir-use-uninitialized-values.cpp index 9f2cbe7a7..ca723a97c 100644 --- a/source/slang/slang-ir-use-uninitialized-values.cpp +++ b/source/slang/slang-ir-use-uninitialized-values.cpp @@ -2,6 +2,7 @@ #include "slang-ir-insts.h" #include "slang-ir-reachability.h" #include "slang-ir.h" +#include "slang-ir-util.h" namespace Slang { @@ -37,30 +38,30 @@ namespace Slang || (inst->m_op == kIROp_Var); } - static bool isUndefinedParam(IRParam* param) + static bool isPotentiallyUnintended(IRParam* param) { - auto outType = as(param->getFullType()); - if (!outType) - return false; - - // Don't check `out Vertices` or `out Indices` parameters - // in mesh shaders. - // TODO: we should find a better way to represent these mesh shader - // parameters so they conform to the initialize before use convention. - // For example, we can use a `OutputVetices` and `OutputIndices` type - // to represent an output, like `OutputPatch` in domain shader. - // For now, we just skip the check for these parameters. - switch (outType->getValueType()->getOp()) - { - case kIROp_VerticesType: - case kIROp_IndicesType: - case kIROp_PrimitivesType: - return false; - default: - break; - } + auto outType = as(param->getFullType()); + if (!outType) + return false; + + // Don't check `out Vertices` or `out Indices` parameters + // in mesh shaders. + // TODO: we should find a better way to represent these mesh shader + // parameters so they conform to the initialize before use convention. + // For example, we can use a `OutputVetices` and `OutputIndices` type + // to represent an output, like `OutputPatch` in domain shader. + // For now, we just skip the check for these parameters. + switch (outType->getValueType()->getOp()) + { + case kIROp_VerticesType: + case kIROp_IndicesType: + case kIROp_PrimitivesType: + return false; + default: + break; + } - return true; + return true; } static bool isAliasable(IRInst* inst) @@ -220,6 +221,15 @@ namespace Slang loads.add(call); } + static void collectSpecialCaseInstructions(List& stores, IRBlock* block) + { + for (auto inst = block->getFirstInst(); inst; inst = inst->next) + { + if (as(inst)) + stores.add(inst); + } + } + static void collectLoadStore(List& stores, List& loads, IRInst* user, IRInst* inst) { // Meta intrinsics (which evaluate on type) do nothing @@ -248,8 +258,6 @@ namespace Slang case kIROp_Store: case kIROp_SwizzledStore: case kIROp_SPIRVAsm: - case kIROp_GenericAsm: - // For now assume that __intrinsic_asm blocks will do the right thing... stores.add(user); break; @@ -277,7 +285,7 @@ namespace Slang } } - static void cancelLoads(ReachabilityContext &reachability, const List& stores, List& loads) + static void cancelLoads(ReachabilityContext& reachability, const List& stores, List& loads) { // Remove all loads which are reachable from stores for (auto store : stores) @@ -292,15 +300,10 @@ namespace Slang } } - static List getUnresolvedParamLoads(ReachabilityContext &reachability, IRFunc* func, IRInst* inst) + static void collectAliasableLoadStores(IRInst* inst, List& stores, List& loads) { - // Collect all aliasable addresses auto addresses = getAliasableInstructions(inst); - // Partition instructions - List stores; - List loads; - for (auto alias : addresses) { // TODO: Mark specific parts assigned to for partial initialization checks @@ -310,15 +313,24 @@ namespace Slang collectLoadStore(stores, loads, user, alias); } } + } + + static List getUnresolvedParamLoads(ReachabilityContext &reachability, IRFunc* func, IRInst* inst) + { + // Partition instructions + List stores; + List loads; + + collectAliasableLoadStores(inst, stores, loads); - // Only for out params we shall add all returns + // Special cases for parameters for (const auto& b : func->getBlocks()) { - auto t = as(b->getTerminator()); - if (!t) - continue; + collectSpecialCaseInstructions(stores, b); - loads.add(t); + auto t = b->getTerminator(); + if (as(t)) + loads.add(t); } cancelLoads(reachability, stores, loads); @@ -328,20 +340,11 @@ namespace Slang static List getUnresolvedVariableLoads(ReachabilityContext &reachability, IRInst* inst) { - auto addresses = getAliasableInstructions(inst); - // Partition instructions List stores; List loads; - for (auto alias : addresses) - { - for (auto use = alias->firstUse; use; use = use->nextUse) - { - IRInst* user = use->getUser(); - collectLoadStore(stores, loads, user, alias); - } - } + collectAliasableLoadStores(inst, stores, loads); cancelLoads(reachability, stores, loads); @@ -497,14 +500,14 @@ namespace Slang // Check out parameters for (auto param : firstBlock->getParams()) { - if (!isUndefinedParam(param)) + if (!isPotentiallyUnintended(param)) continue; auto loads = getUnresolvedParamLoads(reachability, func, param); for (auto load : loads) { sink->diagnose(load, - as (load) + as(load) ? Diagnostics::returningWithUninitializedOut : Diagnostics::usingUninitializedOut, param); -- cgit v1.2.3