Fix ceil(), hypot() and $clog2() codegen - #22
Merged
Conversation
None of these three builtins could be used. Each failed differently and all
for the same underlying reason: no model in the test suite calls them, so the
LLVM path they take was never executed.
ceil(x) "intrinsic llvm.ceil.f64 not found" - the symbol is requested by
Opcode::Ceil but was never declared in CodegenCx::intrinsic, and
Builder::intrinsic turns a missing declaration into unreachable!()
hypot(x,y) declared as double(double) while Opcode::Hypot passes two
arguments, so the module failed the LLVM verifier with
"Incorrect number of arguments passed to called function"
$clog2(x) typed as INT_MATH_2, i.e. two integer arguments, so the spec
conformant single argument call was rejected during type checking
while a two argument call type checked and silently dropped the
second (hir_lower only reads args[0]). Separately the overloaded
ctlz intrinsic was declared unmangled as "llvm.ctlz", which the
verifier rejects with "Intrinsic name not mangled correctly for
type arguments! Should be: llvm.ctlz.i32"
INT_MATH_2 had no other user, so it becomes INT_MATH_1 rather than growing a
second signature.
Adds MATH_INTRINSICS, a model that calls every math builtin routed through
Builder::intrinsic. Arguments derive from a branch voltage so constant folding
cannot evaluate the calls away before they reach codegen, and are kept inside
each function's domain. Without the fixes above the model fails to compile;
with them the full osdi and openvaf integration suites pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three math builtins —
ceil(),hypot()and$clog2()— cannot be used at all onmob. This is independent of the VAMS-2023 work in #19; I found it while checking that my own new builtins were declared correctly inCodegenCx::intrinsic, and it's the same root cause I flagged in #20, so I'd suggest taking this one first.Each fails differently, but all three for one reason: no model in the suite calls them, so the code path is never executed in CI.
What happens today
Minimal model,
ceil:Opcode::Ceilrequestsllvm.ceil.f64, but it was never declared alongsidellvm.floor.f64, andBuilder::intrinsicturns a missing declaration intounreachable!().hypot:It is declared
double(double)whileOpcode::Hypotpasses two arguments, so the module fails the LLVM verifier.$clog2is broken twice over. The spec-conformant single-argument call is rejected up front:because it is typed
INT_MATH_2. Passing two arguments gets past the type checker and then silently discards the second, sincehir_loweronly readsargs[0]. Fixing the signature then exposes the second problem:ctlzis overloaded, so it must carry the type suffix.The fix
Four small changes: declare
llvm.ceil.f64, givehypotits second parameter, retype$clog2to one integer argument, and use the mangledllvm.ctlz.i32.INT_MATH_2had no other user, so it becomesINT_MATH_1rather than adding a second signature next to it.Why a new integration model
I'd rather not fix these and leave the next one to be found by a user, so this adds
MATH_INTRINSICS, which calls every builtin thatBuilder::intrinsicroutes to an LLVM intrinsic or a libm symbol.Two things it has to get right to be worth anything:
unit = x/sqrt(1+x²)forasin/acos/atanh,upper = 1+x²forln/log/acosh— so the test fails on a real codegen problem rather than on aNaN.Reverting any one of the four fixes makes it fail.
Testing
Against LLVM 18.1.8:
cargo test -p osdi— 27/27 (26 existing models plus the new one)cargo test -p openvaf --test integration— 71/71, which compiles the new model to a shared library,dlopens it and processes its parametersRUN_SLOW_TESTS=1 RUN_DEV_TESTS=1— greencargo fmt --all -- --check— cleanTwo pre-existing failures are unrelated and reproduce on a clean
mobcheckout:sourcegen osdi::gen_osdi_structspanics atsourcegen/src/osdi.rs:200, and theverilogaecrate does not compile (CallBackKind::QueryPastStateno longer exists). Neither is built byrust-ci.yml.One note on scope:
$clog2now type-checks one argument, so any model that was passing two to work around the old signature would start erroring. That code was already getting its second argument ignored, so it cannot have been relied on for anything.