Skip to content

Accept $min/$max/$abs system function spelling (VAMS-2023) - #21

Merged
Kreijstal merged 4 commits into
OpenVAF:mobfrom
sai-v-ch:vams2023-min-max-abs
Jul 29, 2026
Merged

Accept $min/$max/$abs system function spelling (VAMS-2023)#21
Kreijstal merged 4 commits into
OpenVAF:mobfrom
sai-v-ch:vams2023-min-max-abs

Conversation

@sai-v-ch

Copy link
Copy Markdown
Collaborator

Adds the alternative Verilog $ spelling for min/max/abs from Verilog-AMS VAMS-2023 (Mantis 7795, table in 4.3.1). In 2.4.0 the $ column for these three is -; VAMS-2023 fills it in with $min, $max, $abs. Second slice of the VAMS-2023 alignment from #19.

Stacked on #20 — please merge that one first. The two touch the same generated tables (sourcegen/src/hir_builtins.rs and the BuiltIn enum it generates), so keeping them independent would have produced a messy conflict in generated code. The diff here is the last commit only; #20's commits appear because GitHub can't base a PR on a branch in my fork.

What changed

These are the same functions as the existing bare min/max/abs, not new ones, and the sysfun::{min,max,abs} name constants already existed. So the whole change is registering the three names in the builtin scope:

dst.insert(sysfun::min, BuiltIn::min.into());
dst.insert(sysfun::max, BuiltIn::max.into());
dst.insert(sysfun::abs, BuiltIn::abs.into());

Signatures, overload resolution and lowering are untouched. Because the variants already existed, nothing in the generated BuiltIn enum got renumbered either.

Testing

The new MIR snapshot covers both the real and the integer overload of all three, showing they lower to the compare+select form the LRM defines them as:

min(x,y) == (x < y) ? x : y
max(x,y) == (x > y) ? x : y
abs(x)   == (x > 0) ? x : -x

Concretely the snapshot shows flt/fgt/fneg for the real overloads and ilt/igt/ineg for the integer ones, so overload resolution is verified rather than assumed.

Also verified against LLVM 18.1.8:

  • cargo test -p osdi — 27/27
  • full frontend suite with RUN_DEV_TESTS=1 — all 26 pre-existing compact models unchanged
  • cargo fmt -- --check clean

As in #20, sourcegen osdi::gen_osdi_structs fails on a clean mob checkout too and is unrelated.

sai-v-ch and others added 4 commits July 28, 2026 22:13
Verilog-AMS VAMS-2023 (Mantis 7780) adds `expm1` and `ln1p` alongside the
existing math builtins. Both are wired up the same way as `exp`/`ln`: as new
MIR unary opcodes, lowered to the libm `expm1`/`log1p` symbols since LLVM has
no intrinsics for them. Both the plain and `$`-prefixed spellings are accepted.

Derivatives:
    d/dx expm1(x) = exp(x)
    d/dx ln1p(x)  = 1/(1+x)

The derivative of expm1 emits `exp(x)` rather than reusing the already
computed `expm1(x) + 1`, which would cancel to zero for large negative x.

The two names are deliberately *not* added to the reserved keyword set even
though VAMS-2023 reserves them: HiSIMSOTB and other compact models written
against older revisions declare their own `expm1` function, and those
declarations must keep shadowing the builtin.

Tests:
  - numeric autodiff checks up to third order plus chain rule cases
  - MIR snapshots for both spellings
  - MIR snapshot proving a user-defined `expm1` still shadows the builtin
  - const folding, including a precision check that ln1p(1e-16) stays 1e-16
    where the naive ln(1+x) folds to 0
`Builder::intrinsic` panics with "intrinsic not found" unless the symbol is
declared in `CodegenCx::intrinsic`, so codegen would have aborted on the first
model that actually called expm1()/ln1p().

No in-tree model used the new builtins (HiSIMSOTB declares its own expm1), so
the OSDI/LLVM harness could not have caught this. Added an integration model
that uses both, which the osdi and openvaf integration harnesses compile
through LLVM.
Verilog-AMS VAMS-2023 (Mantis 7795, table in 4.3.1) adds the alternative
Verilog `$` spelling for min/max/abs, which 2.4.0 did not have.

These map onto the existing `min`/`max`/`abs` builtins, so registering the
three names in the builtin scope is all that is needed; the signatures,
overload resolution and lowering are unchanged.

The added MIR test covers the real and integer overload of all three, showing
they lower to the same compare+select form the LRM defines them as:
    min(x,y) == (x < y) ? x : y
    max(x,y) == (x > y) ? x : y
    abs(x)   == (x > 0) ? x : -x

Co-authored-by: Cursor <cursoragent@cursor.com>
@OpenVAF OpenVAF deleted a comment from gemini-code-assist Bot Jul 29, 2026
@Kreijstal
Kreijstal merged commit a2a6c46 into OpenVAF:mob Jul 29, 2026
8 of 11 checks passed
@sai-v-ch
sai-v-ch deleted the vams2023-min-max-abs branch August 1, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants