[all-commits] [llvm/llvm-project] ec2762: [CIR] Defer indirect goto resolution to GotoSolver...
Adam Smith via All-commits
all-commits at lists.llvm.org
Wed Jul 29 14:04:27 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: ec27629e6f82e17c5f900f6d16ad1d65766cd4e3
https://github.com/llvm/llvm-project/commit/ec27629e6f82e17c5f900f6d16ad1d65766cd4e3
Author: Adam Smith <adams at nvidia.com>
Date: 2026-07-29 (Wed, 29 Jul 2026)
Changed paths:
M clang/include/clang/CIR/Dialect/IR/CIROps.td
M clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
M clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
M clang/lib/CIR/CodeGen/CIRGenFunction.cpp
M clang/lib/CIR/CodeGen/CIRGenFunction.h
M clang/lib/CIR/CodeGen/CIRGenModule.cpp
M clang/lib/CIR/CodeGen/CIRGenModule.h
M clang/lib/CIR/CodeGen/CIRGenStmt.cpp
M clang/lib/CIR/Dialect/Transforms/GotoSolver.cpp
M clang/test/CIR/CodeGen/goto-address-label-table.c
A clang/test/CIR/CodeGen/goto-indirect-cleanup-nyi.c
A clang/test/CIR/CodeGen/goto-indirect-nested.c
M clang/test/CIR/CodeGen/label-values.c
A clang/test/CIR/IR/goto-indirect.cir
M clang/test/CIR/Transforms/goto_solver.cir
Log Message:
-----------
[CIR] Defer indirect goto resolution to GotoSolver (#206176)
A computed `goto *p` placed inside a nested scope -- an if or a loop
body --
made CIRGen produce invalid IR that the region verifier rejected with
"reference to block defined in another region", aborting the compile.
Regular
`goto` avoids this because CIRGen emits a symbolic
`cir.goto` that references no block and is later resolved into a
`cir.br` by
GotoSolver, which runs after FlattenCFG has merged the nested scopes
into one
region. Indirect goto skipped that indirection: `emitIndirectGotoStmt`
built
a real indirect-branch block during CIRGen and branched to it from
inside the
nested region, and `finishIndirectBranch` wired the `cir.indirect_br`
successors at the end of the function -- both while the scopes were
still
separate regions.
This gives indirect goto the same symbolic treatment. A new terminator,
`cir.indirect_goto`, carries the target address and references no
successor,
so it is valid in any region. GotoSolver now rewrites each one into a
`cir.br` to a single shared block holding the `cir.indirect_br` over
every
address-taken label; running after FlattenCFG, it sees all blocks in one
region, so the cross-region branch can no longer occur. GotoSolver
already
collects the address-taken labels -- from `cir.block_address` ops and
from
block-address attributes in global initializers -- so the CIRGen-side
bookkeeping it supersedes (the lazily-built indirect-goto block, the
per-function target list, and the `CIRGenModule` block-address-to-label
map)
is removed.
An indirect goto that branches out of a scope needing cleanup (a VLA
stack
restore, or a non-trivial destructor on the edge) must run that cleanup
on the
branch, which this does not implement. Rather than emit a branch that
silently skips the cleanup, `emitIndirectGotoStmt` reports it with
`errorNYI`.
With the fix, the `evalloop`, `20041214-1`, and `comp-goto-1` programs
in the
LLVM test-suite go from a CIRGen crash to building and running.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list