diff options
| author | Yong He <yonghe@outlook.com> | 2023-05-31 12:36:48 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-31 12:36:48 -0700 |
| commit | 5dd401e416e18fdfe904a66284b0cf56cf256ec7 (patch) | |
| tree | 78c18e41b683261138f1b6349a34057d145a3ae2 /source/slang/slang-ir-sccp.cpp | |
| parent | 57f0ab410766374b155fa546c31812d593480048 (diff) | |
Fix div-by-zero error during sccp. (#2911)
* Diagnose on div-by-zero during sccp.
* fix
---------
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-sccp.cpp')
| -rw-r--r-- | source/slang/slang-ir-sccp.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/source/slang/slang-ir-sccp.cpp b/source/slang/slang-ir-sccp.cpp index 9ad51e0e6..d5e4c6e99 100644 --- a/source/slang/slang-ir-sccp.cpp +++ b/source/slang/slang-ir-sccp.cpp @@ -15,6 +15,7 @@ namespace Slang { struct SharedSCCPContext { IRModule* module; + DiagnosticSink* sink; }; // // Next we have a context struct that will be applied for each function (or other @@ -580,7 +581,7 @@ struct SCCPContext type, v0, v1, - [](IRIntegerValue c0, IRIntegerValue c1) { return c0 / c1; }, + [](IRIntegerValue c0, IRIntegerValue c1) { return c0 / c1; }, [](IRFloatingPointValue c0, IRFloatingPointValue c1) { return c0 / c1; }); } LatticeVal evalEql(IRType* type, LatticeVal v0, LatticeVal v1) @@ -870,10 +871,27 @@ struct SCCPContext getLatticeVal(inst->getOperand(0)), getLatticeVal(inst->getOperand(1))); case kIROp_Div: + { + // Detect divide by zero error. + auto divisor = getLatticeVal(inst->getOperand(1)); + if (divisor.flavor == LatticeVal::Flavor::Constant) + { + if (isIntegralType(divisor.value->getDataType())) + { + auto c = as<IRConstant>(divisor.value); + if (c->value.intVal == 0) + { + if (shared->sink) + shared->sink->diagnose(inst->sourceLoc, Diagnostics::divideByZero); + return LatticeVal::getAny(); + } + } + } return evalDiv( inst->getDataType(), getLatticeVal(inst->getOperand(0)), - getLatticeVal(inst->getOperand(1))); + divisor); + } case kIROp_Eql: return evalEql( inst->getDataType(), @@ -1658,10 +1676,15 @@ static bool applySparseConditionalConstantPropagationRec( } bool applySparseConditionalConstantPropagation( - IRModule* module) + IRModule* module, + DiagnosticSink* sink) { + if (sink && sink->getErrorCount()) + return false; + SharedSCCPContext shared; shared.module = module; + shared.sink = sink; // First we fold constants at global scope. SCCPContext globalContext; @@ -1676,10 +1699,15 @@ bool applySparseConditionalConstantPropagation( } bool applySparseConditionalConstantPropagationForGlobalScope( - IRModule* module) + IRModule* module, + DiagnosticSink* sink) { + if (sink && sink->getErrorCount()) + return false; + SharedSCCPContext shared; shared.module = module; + shared.sink = sink; SCCPContext globalContext; globalContext.shared = &shared; globalContext.code = nullptr; @@ -1687,10 +1715,14 @@ bool applySparseConditionalConstantPropagationForGlobalScope( return changed; } -bool applySparseConditionalConstantPropagation(IRInst* func) +bool applySparseConditionalConstantPropagation(IRInst* func, DiagnosticSink* sink) { + if (sink && sink->getErrorCount()) + return false; + SharedSCCPContext shared; shared.module = func->getModule(); + shared.sink = sink; SCCPContext globalContext; globalContext.shared = &shared; |
