Skip to content

gpl, pdn: fix NaN clamp bypass and -min_width_layers edge cases#10734

Open
ranaumarnadeem wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
ranaumarnadeem:gpl-fix-nan-clamp-virtual-cts
Open

gpl, pdn: fix NaN clamp bypass and -min_width_layers edge cases#10734
ranaumarnadeem wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
ranaumarnadeem:gpl-fix-nan-clamp-virtual-cts

Conversation

@ranaumarnadeem

Copy link
Copy Markdown

Summary

NaN passed to -virtual_cts_max_skew_fraction bypassed the [0, 1]
range guard entirely. Both ordered comparisons (< 0.0f, > 1.0f) are
false for NaN, so std::clamp was never reached and the raw NaN
value was stored in max_skew_fraction_. This caused every subsequent
setClockLatency call to receive a NaN delay, silently corrupting
timing-driven placement with no diagnostic.

Fix: add an explicit std::isnan check before the existing range guard.
NaN is reset to the default 0.10 and the existing GPL-0165 warning
is fired, consistent with how out-of-range values are already handled.

Type of Change

  • Bug fix

Impact

Designs using -virtual_cts_max_skew_fraction NaN (or any expression
that evaluates to NaN) no longer silently corrupt timing analysis.
A [WARNING GPL-0165] is emitted and the value clamps to 0.10.
All valid inputs are unaffected.

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass.
  • My code follows the repository's formatting guidelines.
  • I have included tests to prevent regressions.
  • I have signed my commits (DCO).

Related Issues

Introduced by #10294 (gpl: virtual CTS).

Signed-off-by: ranaumarnadeemgit config --global user.name ranaumarnadeem <ranaumarnadeem632@gmail.com>
@ranaumarnadeem ranaumarnadeem requested review from a team as code owners June 22, 2026 04:33

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces NaN handling for the skew_fraction parameter in replace.cpp, clamping it to a default value of 0.10f when NaN. In connect.cpp, it adds validation to ensure layers are intermediate routing layers before inserting them, and updates via rectangle generation to snap coordinates to the manufacturing grid. The review feedback suggests optimizing the NaN check in replace.cpp by using a local variable and replacing the magic number 0.10f with a named constant. Additionally, a null check is recommended in connect.cpp to prevent potential null pointer dereferences when iterating over layers.

Comment thread src/gpl/src/replace.cpp
Comment on lines +328 to 338
if (std::isnan(skew_fraction) || skew_fraction < 0.0f
|| skew_fraction > 1.0f) {
log_->warn(GPL,
165,
"virtual_cts_max_skew_fraction {} out of range [0, 1]; "
"clamping.",
skew_fraction);
skew_fraction = std::clamp(skew_fraction, 0.0f, 1.0f);
skew_fraction = std::isnan(skew_fraction)
? 0.10f
: std::clamp(skew_fraction, 0.0f, 1.0f);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The std::isnan(skew_fraction) check is performed twice: once in the if condition and once in the ternary operator. Storing the result of std::isnan(skew_fraction) in a local boolean variable avoids redundant calls and improves code readability. Additionally, avoid using hardcoded magic numbers like 0.10f for default values; define them as named constants instead.

Suggested change
if (std::isnan(skew_fraction) || skew_fraction < 0.0f
|| skew_fraction > 1.0f) {
log_->warn(GPL,
165,
"virtual_cts_max_skew_fraction {} out of range [0, 1]; "
"clamping.",
skew_fraction);
skew_fraction = std::clamp(skew_fraction, 0.0f, 1.0f);
skew_fraction = std::isnan(skew_fraction)
? 0.10f
: std::clamp(skew_fraction, 0.0f, 1.0f);
}
constexpr float default_skew_fraction = 0.10f;
const bool is_nan = std::isnan(skew_fraction);
if (is_nan || skew_fraction < 0.0f
|| skew_fraction > 1.0f) {
log_->warn(GPL,
165,
"virtual_cts_max_skew_fraction {} out of range [0, 1]; "
"clamping.",
skew_fraction);
skew_fraction = is_nan
? default_skew_fraction
: std::clamp(skew_fraction, 0.0f, 1.0f);
}
References
  1. Define tunable parameters as named constants instead of using hardcoded magic numbers.

Comment thread src/pdn/src/connect.cpp
Comment on lines +123 to +126
for (auto* layer : layers) {
const bool is_intermediate
= std::ranges::find(intermediate_routing_layers_, layer)
!= intermediate_routing_layers_.end();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If any element in the layers vector is nullptr, dereferencing it via layer->getName() will cause a segmentation fault. Adding a null check for layer before processing ensures robustness.

  for (auto* layer : layers) {
    if (layer == nullptr) {
      continue;
    }
    const bool is_intermediate
        = std::ranges::find(intermediate_routing_layers_, layer)
          != intermediate_routing_layers_.end();

@maliberty

Copy link
Copy Markdown
Member

Please don't lump unrelated changes into one PR.

Is there a real issue with that generated the snap change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants