lfortran / lfortran

Official main repository for LFortran
https://lfortran.org/
Other
940 stars 151 forks source link

ASR: add support for "nearest" #4024

Open certik opened 4 months ago

certik commented 4 months ago

Most likely this has to be a new expr node, something like RealNearest. Let's first figure out an LLVM (and WASM) instructions to compute it, as well as x86/arm assembly instructions, so that we know how to compute this. And then design a nice ASR node for this.

Pranavchiku commented 4 months ago

This is one way to do it in LLVM, although generated by ChatGPT, it looks reasonably correct.

Edit: Not sure though, will need to dig deeper.

; Declare the function signature
define double @nearest(double %x, double %s) {
entry:
    ; Get the sign bit of %s
    %sign_bit = fcmp olt double %s, 0.0

    ; Compute the positive nearest value
    %positive_nearest = call double @llvm.nearbyint.f64(double %x)

    ; Compute the negative nearest value
    %negative_nearest = call double @llvm.nearbyint.f64(double -%x)
    %negative_nearest = fneg double %negative_nearest

    ; Select the result based on the sign of %s
    %result = select i1 %sign_bit, double %negative_nearest, double %positive_nearest

    ; Return the result
    ret double %result
}

; Declare the LLVM intrinsic function for rounding to the nearest integer
declare double @llvm.nearbyint.f64(double)