Skip to content

Is our handling of % correct? #32

Description

@captbaritone

Trying compile C's fmod to wasm results in dramatically more code:

Try the following in https://webassembly.studio/

#define WASM_EXPORT __attribute__((visibility("default")))
#include <math.h>

WASM_EXPORT
double mod(double a, double b)
{
    return fmod(a, b);
}

WASM_EXPORT
int main()
{
    return 42;
}

And you will get the following wat:

(module
  (type $t0 (func))
  (type $t1 (func (param f64 f64) (result f64)))
  (type $t2 (func (result i32)))
  (func $__wasm_call_ctors (type $t0))
  (func $mod (export "mod") (type $t1) (param $p0 f64) (param $p1 f64) (result f64)
    get_local $p0
    get_local $p1
    call $fmod)
  (func $main (export "main") (type $t2) (result i32)
    i32.const 42)
  (func $fmod (type $t1) (param $p0 f64) (param $p1 f64) (result f64)
    (local $l0 i64) (local $l1 i64) (local $l2 i64) (local $l3 i32) (local $l4 i64) (local $l5 i32) (local $l6 i32)
    block $B0
      block $B1
        block $B2
          block $B3
            block $B4
              block $B5
                get_local $p1
                i64.reinterpret/f64
                tee_local $l0
                i64.const 1
                i64.shl
                tee_local $l1
                i64.eqz
                br_if $B5
                get_local $l0
                i64.const 9223372036854775807
                i64.and
                i64.const 9218868437227405312
                i64.gt_u
                br_if $B5
                get_local $p0
                i64.reinterpret/f64
                tee_local $l2
                i64.const 52
                i64.shr_u
                i32.wrap/i64
                i32.const 2047
                i32.and
                tee_local $l3
                i32.const 2047
                i32.eq
                br_if $B5
                get_local $l2
                i64.const 1
                i64.shl
                tee_local $l4
                get_local $l1
                i64.le_u
                br_if $B4
                get_local $l0
                i64.const 52
                i64.shr_u
                i32.wrap/i64
                i32.const 2047
                i32.and
                set_local $l5
                get_local $l3
                i32.eqz
                br_if $B3
                get_local $l2
                i64.const 4503599627370495
                i64.and
                i64.const 4503599627370496
                i64.or
                set_local $l1
                get_local $l5
                i32.eqz
                br_if $B2
                br $B1
              end
              get_local $p0
              get_local $p1
              f64.mul
              tee_local $p1
              get_local $p1
              f64.div
              return
            end
            get_local $p0
            f64.const 0x0p+0 (;=0;)
            f64.mul
            get_local $p0
            get_local $l4
            get_local $l1
            i64.eq
            select
            return
          end
          i32.const 0
          set_local $l3
          block $B6
            get_local $l2
            i64.const 12
            i64.shl
            tee_local $l1
            i64.const 0
            i64.lt_s
            br_if $B6
            loop $L7
              get_local $l3
              i32.const -1
              i32.add
              set_local $l3
              get_local $l1
              i64.const 1
              i64.shl
              tee_local $l1
              i64.const -1
              i64.gt_s
              br_if $L7
            end
          end
          get_local $l2
          i32.const 1
          get_local $l3
          i32.sub
          i64.extend_u/i32
          i64.shl
          set_local $l1
          get_local $l5
          br_if $B1
        end
        i32.const 0
        set_local $l5
        block $B8
          get_local $l0
          i64.const 12
          i64.shl
          tee_local $l4
          i64.const 0
          i64.lt_s
          br_if $B8
          loop $L9
            get_local $l5
            i32.const -1
            i32.add
            set_local $l5
            get_local $l4
            i64.const 1
            i64.shl
            tee_local $l4
            i64.const -1
            i64.gt_s
            br_if $L9
          end
        end
        get_local $l0
        i32.const 1
        get_local $l5
        i32.sub
        i64.extend_u/i32
        i64.shl
        set_local $l0
        br $B0
      end
      get_local $l0
      i64.const 4503599627370495
      i64.and
      i64.const 4503599627370496
      i64.or
      set_local $l0
    end
    get_local $l1
    get_local $l0
    i64.sub
    tee_local $l4
    i64.const -1
    i64.gt_s
    set_local $l6
    block $B10
      block $B11
        block $B12
          get_local $l3
          get_local $l5
          i32.le_s
          br_if $B12
          loop $L13
            block $B14
              get_local $l6
              i32.const 1
              i32.and
              i32.eqz
              br_if $B14
              get_local $l4
              set_local $l1
              get_local $l4
              i64.const 0
              i64.eq
              br_if $B11
            end
            get_local $l1
            i64.const 1
            i64.shl
            tee_local $l1
            get_local $l0
            i64.sub
            tee_local $l4
            i64.const -1
            i64.gt_s
            set_local $l6
            get_local $l3
            i32.const -1
            i32.add
            tee_local $l3
            get_local $l5
            i32.gt_s
            br_if $L13
          end
        end
        block $B15
          get_local $l6
          i32.eqz
          br_if $B15
          get_local $l4
          set_local $l1
          get_local $l4
          i64.const 0
          i64.eq
          br_if $B10
        end
        block $B16
          get_local $l1
          i64.const 4503599627370495
          i64.gt_u
          br_if $B16
          loop $L17
            get_local $l3
            i32.const -1
            i32.add
            set_local $l3
            get_local $l1
            i64.const 1
            i64.shl
            tee_local $l1
            i64.const 4503599627370496
            i64.lt_u
            br_if $L17
          end
        end
        get_local $l2
        i64.const -9223372036854775808
        i64.and
        set_local $l4
        block $B18
          get_local $l3
          i32.const 1
          i32.lt_s
          br_if $B18
          get_local $l1
          i64.const -4503599627370496
          i64.add
          get_local $l3
          i64.extend_u/i32
          i64.const 52
          i64.shl
          i64.or
          get_local $l4
          i64.or
          f64.reinterpret/i64
          return
        end
        get_local $l1
        i32.const 1
        get_local $l3
        i32.sub
        i64.extend_u/i32
        i64.shr_u
        get_local $l4
        i64.or
        f64.reinterpret/i64
        return
      end
      get_local $p0
      f64.const 0x0p+0 (;=0;)
      f64.mul
      return
    end
    get_local $p0
    f64.const 0x0p+0 (;=0;)
    f64.mul)
  (table $T0 1 1 anyfunc)
  (memory $memory (export "memory") 2)
  (global $g0 (mut i32) (i32.const 66560))
  (global $__heap_base (export "__heap_base") i32 (i32.const 66560))
  (global $__data_end (export "__data_end") i32 (i32.const 1024)))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions