MikeInnes / Charlotte.jl

Charlotte's Web Scale
Other
113 stars 13 forks source link

|| operator doesn't work #19

Closed sjorn3 closed 6 years ago

sjorn3 commented 6 years ago

I haven't tried other operators, but I wouldn't be surprised if the same problem exists. Essentially the second argument to the or is ignored. This problem exists on both julia-0.7 and master.

this(x) = x == 1 || x == 0 ? 1 : 0
(module
  (export "this" (func $#this_Int64))
  (memory 1)
  (func $#this_Int64  (param i64) (result i64)
  (local i32) (local i32)
    (block
      (block
        (get_local 0)
        (i64.const 1)
        (i64.eq)
        (set_local 2)
        (get_local 2)
        (if
          (then
            (get_local 2)
            (set_local 1)        <- save result of x == 1
            (br 1))))            <- works if (br 2), skipping next comparison.
      (get_local 0)
      (i64.const 0)
      (i64.eq)
      (set_local 1))             <- result of x == 0
    (get_local 1)
    (if
      (then
        (i64.const 1)
        (return)))               <- return 1 if saved result was true
    (i64.const 0)
    (return)))

This might be a simple fix but I haven't looked into it much yet. I think the issue might be in restructuring in WebAssembly.

tshort commented 6 years ago

I don't know if this helps at all, but here's some output from ExportWebAssembly for this same function with optimizations off.

(module
  (type (;0;) (func (param i64) (result i64)))
  (type (;1;) (func (result i32)))
  (import "env" "julia.ptls_states" (func $julia.ptls_states (type 1)))
  (func $julia_this_35625 (type 0) (param i64) (result i64)
    (local i32)
    get_global 0
    i32.const 16
    i32.sub
    tee_local 1
    set_global 0
    call $julia.ptls_states
    drop
    get_local 1
    get_local 0
    i64.const 1
    i64.eq
    i32.store8 offset=15
    block  ;; label = @1
      block  ;; label = @2
        block  ;; label = @3
          get_local 0
          i64.const 1
          i64.eq
          br_if 0 (;@3;)
          get_local 1
          get_local 0
          i64.eqz
          i32.store8 offset=14
          get_local 1
          i32.load8_u offset=14
          i32.const 1
          i32.and
          i32.eqz
          br_if 1 (;@2;)
          br 2 (;@1;)
        end
        get_local 1
        i32.load8_u offset=15
        i32.const 1
        i32.and
        br_if 1 (;@1;)
      end
      get_local 1
      i32.const 16
      i32.add
      set_global 0
      i64.const 0
      return
    end
    get_local 1
    i32.const 16
    i32.add
    set_global 0
    i64.const 1)
  (table (;0;) 1 1 anyfunc)
  (memory (;0;) 2)
  (global (;0;) (mut i32) (i32.const 66560))
  (export "memory" (memory 0))
  (export "julia_this_35625" (func $julia_this_35625)))

ExportWebAssembly is still clumsy to get to wast. I need to export to .bc, get to .o with llc, compile to .wasm with lld, and finally convert to .wast with wasm2wast.

sjorn3 commented 6 years ago

Fixed with this pull