Skip to content

mpl: check core containment against the post-orientation footprint - #11155

Merged
AcKoucher merged 4 commits into
The-OpenROAD-Project:masterfrom
sfmth:master
Aug 22, 2026
Merged

mpl: check core containment against the post-orientation footprint#11155
AcKoucher merged 4 commits into
The-OpenROAD-Project:masterfrom
sfmth:master

Conversation

@sfmth

@sfmth sfmth commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

MacroPlacer::placeMacro built its core-containment rectangle from
inst->getBBox() and raised MPL-0034 at src/mpl/src/rtl_mp.cpp:109, but did
not call inst->setOrient(orientation) until 24 lines later. Since getBBox()
returns the bounding box cached for the instance's current orientation, any
request whose orientation differs in right-angle-ness from the current one was
validated against the wrong footprint — the four right-angle orientations
(R90, R270, MXR90, MYR90) swap width and height.

This computes the width and height the macro will actually have once
orientation is applied and validates that instead. The comparison is made
against the instance's current orientation rather than assuming R0, so a macro
that has already been rotated — for example by an earlier attempt in a caller's
retry loop, which may reset placement status without resetting orientation — is
handled correctly rather than double-swapped.

The existing comment two lines below the check ("Orientation must be set before
location so we don't end up flipping and misplacing the macro") shows the
ordering of setOrient/setLocation was deliberate; only the containment test
was left above both.

Type of Change

  • Bug fix

Impact

place_macro now validates core containment against the footprint the macro will
have after the requested orientation is applied, rather than the one it
currently has. Only calls that change the instance's right-angle-ness are
affected: placements at R0/R180/MX/MY on an unrotated instance take the
identical path as before, square macros are unaffected, and the existing mpl
suite passes unchanged (36/36). For the four right-angle orientations two
behaviours change, in opposite directions. A legal placement of a rotated
non-square macro is no longer rejected — previously it was measured against its
unrotated footprint, so a macro that fits only when rotated was refused with
MPL-0034; the new test is exactly this case, a 100×400 µm macro placed at R90
in a 499.89×198.80 µm core. Symmetrically, a rotated macro that genuinely does
not fit is now caught, where before the swapped dimensions could let it pass the
check and be placed and LOCKED outside the core. That second direction is the
one to be aware of when upgrading: a flow that previously appeared to succeed may
now report MPL-0034, but the placement it produced was already out of bounds and
simply went undetected.

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
    Built at cbc7678e45 with the equivalent direct invocation:
    cmake -B build -G Ninja && ninja -C build openroad (Release, gcc).
  • I have run the relevant tests and they pass.
    src/mpl/test/./regression36/36 mpl tests pass, including the new one.
  • My code follows the repository's formatting guidelines.
    clang-format -i src/mpl/src/rtl_mp.cpp applied.
  • I have included tests to prevent regressions.
    place_macro_rotated, registered in both CMakeLists.txt and BUILD.
  • I have signed my commits (DCO).

Evidence the test catches the bug

The same test, same testcase, against a binary built from unpatched source versus
the patched one:

binary result
unpatched (26Q2-1164-g08f67ee5ec) aborts at the R90 call — [ERROR MPL-0034] Cannot place macro at (20, 20) (120, 420), outside of the core (0, 0) (499.89, 198.8).
patched (26Q3-1297-gcbc7678e45) [INFO MPL-0035] Macro macro placed. Bounding box (20.000um, 20.000um), (420.000um, 120.000um). Orientation R90

The rejected rectangle in the failing case, (120, 420), is the macro's
unrotated 100×400 footprint offset by the requested origin — the bug is visible
in the error message itself. The accepted rectangle is the rotated 400×100
footprint, which fits the core.

The test also asserts that the same origin is still rejected at R0, where
the macro genuinely does not fit, so the change cannot silently over-correct in
the permissive direction.

Related Issues

None filed — reporting directly via this PR. The defect is reachable from the
public place_macro command for any caller that passes a right-angle orientation
for a non-square macro; HierRTLMP::placeMacros uses a separate commit path and
is unaffected.

@sfmth
sfmth requested a review from a team as a code owner August 16, 2026 04:36
@sfmth
sfmth requested a review from AcKoucher August 16, 2026 04:36

@github-actions github-actions 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.

Welcome to OpenROAD! Thanks for opening your first PR.
Before we review:

Please ensure:

  • CI passes
  • Code is properly formatted
  • Tests are included where applicable
    A maintainer will review shortly!

@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 updates the macro containment validation in MacroPlacer::placeMacro to use the correct footprint of the macro after the requested orientation is applied. Specifically, it swaps the width and height if the requested orientation differs in right-angle rotation from the current orientation, preventing legal rotated placements from being rejected and illegal ones from being accepted. A new integration test, place_macro_rotated, has been added to verify this fix. There are no review comments, and I have no additional feedback to provide.

@AcKoucher AcKoucher 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.

Hi, @sfmth! Thanks for catching this.

Comment thread src/mpl/src/rtl_mp.cpp Outdated
Comment thread src/mpl/test/CMakeLists.txt Outdated
Comment thread src/mpl/test/place_macro_rotated.tcl Outdated
@sfmth

sfmth commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

@AcKoucher
applied the requested changes

@AcKoucher
AcKoucher self-requested a review August 21, 2026 21:26

@AcKoucher AcKoucher 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.

Please, adapt the names of the files to be place_macro_right_angle_rotation so that we have everything consistent.

Comment thread src/mpl/test/place_macro_rotated.tcl Outdated
Comment thread src/mpl/test/place_macro_rotated.tcl Outdated
Comment thread src/mpl/test/place_macro_rotated.tcl Outdated
Comment thread src/mpl/test/place_macro_rotated.tcl Outdated
Comment thread src/mpl/src/rtl_mp.cpp Outdated
@sfmth

sfmth commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

@AcKoucher
ok removed comments and renamed the files

sfmth added 4 commits August 21, 2026 16:54
place_macro validated the core-containment rectangle using the
instance's
bounding box *before* the requested orientation was applied. The four
right-angle orientations (R90, R270, MXR90, MYR90)
swap width and height, so whenever the requested orientation differed
from the current one in right-angle-ness the check used the wrong
footprint: it rejected legal placements of rotated macros with
MPL-0034, and symmetrically would accept ones that do not fit.

Compute the width and height the macro will actually have once
`orientation` is applied, and validate that instead. The comparison is
made against the instance's current orientation rather than assuming
R0, so a macro that has already been rotated is handled correctly too.

The new test places a 100x400um macro at R90 in a 499.89x198.80um
core, where the rotated footprint (400x100) fits and the unrotated one
(100x400) does not. It also asserts the same origin is still rejected
at R0, so the fix cannot silently over-correct.

Signed-off-by: sfmth <sfmth0@gmail.com>
The new test was added to COMPULSORY_TESTS but not to the per-test
resource dict. src/mpl/test/BUILD does not glob the testcases/
directory -- the filegroup globs only `test_name + ".*"`, which picks up
the .tcl, .ok and .defok, so each test's LEF and DEF have to be listed
explicitly.

The Bazel target therefore resolved and ran without
testcases/place_macro_rotated.{lef,def}, while the CMake build passed
because it collects test inputs differently.

bazel query deps(//src/mpl/test:place_macro_rotated_resources) now lists
all six required inputs, and
bazel test //src/mpl/test:place_macro_rotated-tcl_test passes.

Signed-off-by: sfmth <sfmth0@gmail.com>
Set the orientation before building the containment rectangle instead of
computing the post-orientation footprint by hand, per review. getBBox()
then already reports the footprint the macro will have, so the explicit
width/height swap and its right-angle-ness comparison are unnecessary.
setOrient() had to precede setLocation() in any case; it now precedes
the
core-containment check as well.

Rename the test to place_macro_with_right_angle_rotation and reduce it
to
the single R90 placement. The negative case it also asserted is no
longer
sound: with setOrient() ahead of the check, a rejected placement leaves
the instance rotated, so catching MPL-0034 and then writing the DEF
would
serialize the macro at the rejected orientation.

Signed-off-by: sfmth <sfmth0@gmail.com>
Rename the test and all five of its files to
place_macro_right_angle_rotation, so the CMake test name, the Bazel
targets, the .tcl/.ok/.defok and the testcases LEF/DEF agree. The
half-applied rename currently on the PR branch renamed only the Bazel
entries, which fails the package load -- "Error in glob: glob pattern
'place_macro_with_right_angle_rotation.*' didn't match anything" -- and
takes all of Jenkins down with it.

Reword the comment above setOrient() and cut the test down to its header
line, both verbatim as requested in review.

Signed-off-by: sfmth <sfmth0@gmail.com>
@sfmth

sfmth commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

fixed DCO check

@AcKoucher AcKoucher 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.

@sfmth Thanks for fixing the DCO but be careful on future contributions: please, don't force-push after a review as we lose the history.

@AcKoucher
AcKoucher merged commit ee3485c into The-OpenROAD-Project:master Aug 22, 2026
16 checks passed
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