Fix dist range bounds over rand variables failing randomization since #7802
This commit is contained in:
parent
119493ee8a
commit
5797913600
|
|
@ -4571,31 +4571,47 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
continue;
|
||||
}
|
||||
|
||||
const auto boundRefsRandVarp = [](const AstNode* boundp) -> bool {
|
||||
bool found = false;
|
||||
boundp->foreach([&](const AstVarRef* vrefp) {
|
||||
if (vrefp->varp()->rand().isRandomizable()) found = true;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
// (distExpr >= lo) && (distExpr <= hi); signed comparisons for signed vars
|
||||
const auto rangeMembershipp = [&](const AstInsideRange* irp) -> AstNodeExpr* {
|
||||
const bool isSigned = distp->exprp()->isSigned();
|
||||
AstNodeExpr* const distExprGtep = distp->exprp()->cloneTreePure(false);
|
||||
AstNodeExpr* const distExprLtep = distp->exprp()->cloneTreePure(false);
|
||||
distExprGtep->user1(true);
|
||||
distExprLtep->user1(true);
|
||||
AstNodeExpr* const gep
|
||||
= isSigned
|
||||
? static_cast<AstNodeExpr*>(
|
||||
new AstGteS{fl, distExprGtep, irp->lhsp()->cloneTreePure(false)})
|
||||
: static_cast<AstNodeExpr*>(
|
||||
new AstGte{fl, distExprGtep, irp->lhsp()->cloneTreePure(false)});
|
||||
AstNodeExpr* const lep
|
||||
= isSigned
|
||||
? static_cast<AstNodeExpr*>(
|
||||
new AstLteS{fl, distExprLtep, irp->rhsp()->cloneTreePure(false)})
|
||||
: static_cast<AstNodeExpr*>(
|
||||
new AstLte{fl, distExprLtep, irp->rhsp()->cloneTreePure(false)});
|
||||
gep->user1(true);
|
||||
lep->user1(true);
|
||||
AstNodeExpr* const andp = new AstLogAnd{fl, gep, lep};
|
||||
andp->user1(true);
|
||||
return andp;
|
||||
};
|
||||
|
||||
// IEEE 1800-2023 18.5.3: values not in the distribution must never appear.
|
||||
// Build the union of all non-zero-weight ranges as a single hard ConstraintExpr
|
||||
AstNodeExpr* unionExprp = nullptr;
|
||||
for (const auto& bucket : buckets) {
|
||||
AstNodeExpr* memberp;
|
||||
if (const AstInsideRange* const irp = VN_CAST(bucket.rangep, InsideRange)) {
|
||||
// (distExpr >= lo) && (distExpr <= hi); signed comparisons for signed vars
|
||||
const bool isSigned = distp->exprp()->isSigned();
|
||||
AstNodeExpr* const distExprGtep = distp->exprp()->cloneTreePure(false);
|
||||
AstNodeExpr* const distExprLtep = distp->exprp()->cloneTreePure(false);
|
||||
distExprGtep->user1(true);
|
||||
distExprLtep->user1(true);
|
||||
AstNodeExpr* const gep
|
||||
= isSigned ? static_cast<AstNodeExpr*>(new AstGteS{
|
||||
fl, distExprGtep, irp->lhsp()->cloneTreePure(false)})
|
||||
: static_cast<AstNodeExpr*>(new AstGte{
|
||||
fl, distExprGtep, irp->lhsp()->cloneTreePure(false)});
|
||||
AstNodeExpr* const lep
|
||||
= isSigned ? static_cast<AstNodeExpr*>(new AstLteS{
|
||||
fl, distExprLtep, irp->rhsp()->cloneTreePure(false)})
|
||||
: static_cast<AstNodeExpr*>(new AstLte{
|
||||
fl, distExprLtep, irp->rhsp()->cloneTreePure(false)});
|
||||
gep->user1(true);
|
||||
lep->user1(true);
|
||||
memberp = new AstLogAnd{fl, gep, lep};
|
||||
memberp = rangeMembershipp(irp);
|
||||
} else {
|
||||
// distExpr == val
|
||||
AstNodeExpr* const distExprCopyp = distp->exprp()->cloneTreePure(false);
|
||||
|
|
@ -4673,7 +4689,12 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstNode* chainp = nullptr;
|
||||
for (int i = static_cast<int>(buckets.size()) - 1; i >= 0; --i) {
|
||||
AstNodeExpr* constraintExprp;
|
||||
if (const AstInsideRange* const irp = VN_CAST(buckets[i].rangep, InsideRange)) {
|
||||
const AstInsideRange* const irp = VN_CAST(buckets[i].rangep, InsideRange);
|
||||
if (irp && (boundRefsRandVarp(irp->lhsp()) || boundRefsRandVarp(irp->rhsp()))) {
|
||||
// Bounds solved concurrently cannot pin a pre-solve value; softly
|
||||
// prefer the symbolic range so the hard membership stays satisfiable
|
||||
constraintExprp = rangeMembershipp(irp);
|
||||
} else if (irp) {
|
||||
// Pick distExpr = lo + rand64() % (hi - lo + 1) for a uniform value in range
|
||||
AstNodeExpr* const distExprCopyp = distp->exprp()->cloneTreePure(false);
|
||||
distExprCopyp->user1(true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue