diff options
-rw-r--r-- | src/asm2wasm.h | 13 | ||||
-rw-r--r-- | src/emscripten-optimizer/parser.cpp | 1 | ||||
-rw-r--r-- | src/emscripten-optimizer/parser.h | 1 | ||||
-rw-r--r-- | test/emcc_hello_world.asm.js | 12 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 98 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 98 | ||||
-rw-r--r-- | test/min.asm.js | 4 | ||||
-rw-r--r-- | test/min.fromasm | 7 | ||||
-rw-r--r-- | test/min.fromasm.imprecise | 7 |
9 files changed, 35 insertions, 206 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 910134024..1aca67eff 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -202,6 +202,8 @@ private: IString Math_ceil; IString Math_sqrt; + IString llvm_cttz_i32; + IString tempDoublePtr; // imported name of tempDoublePtr // function types. we fill in this information as we see @@ -486,10 +488,15 @@ void Asm2WasmBuilder::processAsm(Ref ast) { assert(module[0] == NAME); moduleName = module[1]->getIString(); if (moduleName == ENV) { - if (imported[2] == TEMP_DOUBLE_PTR) { + auto base = imported[2]->getIString(); + if (base == TEMP_DOUBLE_PTR) { assert(tempDoublePtr.isNull()); tempDoublePtr = name; // we don't return here, as we can only optimize out some uses of tDP. So it remains imported + } else if (base == LLVM_CTTZ_I32) { + assert(llvm_cttz_i32.isNull()); + llvm_cttz_i32 = name; + return; } } } @@ -1092,10 +1099,10 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->type = WasmType::i32; return ret; } - if (name == Math_clz32) { + if (name == Math_clz32 || name == llvm_cttz_i32) { assert(ast[2]->size() == 1); auto ret = allocator.alloc<Unary>(); - ret->op = Clz; + ret->op = name == Math_clz32 ? Clz : Ctz; ret->value = process(ast[2][0]); ret->type = WasmType::i32; return ret; diff --git a/src/emscripten-optimizer/parser.cpp b/src/emscripten-optimizer/parser.cpp index 7005dc4b4..ce4737476 100644 --- a/src/emscripten-optimizer/parser.cpp +++ b/src/emscripten-optimizer/parser.cpp @@ -48,6 +48,7 @@ IString TOPLEVEL("toplevel"), INF("inf"), NaN("nan"), TEMP_RET0("tempRet0"), + LLVM_CTTZ_I32("_llvm_cttz_i32"), UNARY_PREFIX("unary-prefix"), UNARY_POSTFIX("unary-postfix"), MATH_FROUND("Math_fround"), diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h index da3e6f5c7..e10044fbc 100644 --- a/src/emscripten-optimizer/parser.h +++ b/src/emscripten-optimizer/parser.h @@ -63,6 +63,7 @@ extern IString TOPLEVEL, INF, NaN, TEMP_RET0, + LLVM_CTTZ_I32, UNARY_PREFIX, UNARY_POSTFIX, MATH_FROUND, diff --git a/test/emcc_hello_world.asm.js b/test/emcc_hello_world.asm.js index 6b904c741..3a47a258b 100644 --- a/test/emcc_hello_world.asm.js +++ b/test/emcc_hello_world.asm.js @@ -77,6 +77,7 @@ Module["asm"] = (function(global, env, buffer) { var _pthread_cleanup_push=env._pthread_cleanup_push; var _sysconf=env._sysconf; var ___syscall146=env.___syscall146; + var _llvm_cttz_i32=env._llvm_cttz_i32; var tempFloat = 0.0; // EMSCRIPTEN_START_FUNCS @@ -6757,17 +6758,6 @@ function _bitshift64Ashr(low, high, bits) { tempRet0 = (high|0) < 0 ? -1 : 0; return (high >> (bits - 32))|0; } -function _llvm_cttz_i32(x) { - x = x|0; - var ret = 0; - ret = ((HEAP8[(((cttz_i8)+(x & 0xff))>>0)])|0); - if ((ret|0) < 8) return ret|0; - ret = ((HEAP8[(((cttz_i8)+((x >> 8)&0xff))>>0)])|0); - if ((ret|0) < 8) return (ret + 8)|0; - ret = ((HEAP8[(((cttz_i8)+((x >> 16)&0xff))>>0)])|0); - if ((ret|0) < 8) return (ret + 16)|0; - return (((HEAP8[(((cttz_i8)+(x >>> 24))>>0)])|0) + 24)|0; - } // ======== compiled code from system/lib/compiler-rt , see readme therein function ___muldsi3($a, $b) { diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index be7a45cec..5c41777c7 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -28552,100 +28552,6 @@ ) ) ) - (func $_llvm_cttz_i32 (param $x i32) (result i32) - (local $ret i32) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (get_local $x) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (get_local $ret) - ) - ) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (i32.shr_s - (get_local $x) - (i32.const 8) - ) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (i32.add - (get_local $ret) - (i32.const 8) - ) - ) - ) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (i32.shr_s - (get_local $x) - (i32.const 16) - ) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (i32.add - (get_local $ret) - (i32.const 16) - ) - ) - ) - (return - (i32.add - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.shr_u - (get_local $x) - (i32.const 24) - ) - ) - ) - (i32.const 24) - ) - ) - ) (func $___muldsi3 (param $$a i32) (param $$b i32) (result i32) (local $$8 i32) (local $$6 i32) @@ -29580,7 +29486,7 @@ (set_local $$_0$0 (i32.shr_u (get_local $$n_sroa_1_4_extract_trunc) - (call $_llvm_cttz_i32 + (i32.ctz (get_local $$d_sroa_1_4_extract_trunc) ) ) @@ -30055,7 +29961,7 @@ ) (block (set_local $$78 - (call $_llvm_cttz_i32 + (i32.ctz (get_local $$d_sroa_0_0_extract_trunc) ) ) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index fc4418930..52c1444b6 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -28550,100 +28550,6 @@ ) ) ) - (func $_llvm_cttz_i32 (param $x i32) (result i32) - (local $ret i32) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (get_local $x) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (get_local $ret) - ) - ) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (i32.shr_s - (get_local $x) - (i32.const 8) - ) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (i32.add - (get_local $ret) - (i32.const 8) - ) - ) - ) - (if - (i32.lt_s - (set_local $ret - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.and - (i32.shr_s - (get_local $x) - (i32.const 16) - ) - (i32.const 255) - ) - ) - ) - ) - (i32.const 8) - ) - (return - (i32.add - (get_local $ret) - (i32.const 16) - ) - ) - ) - (return - (i32.add - (i32.load8_s - (i32.add - (i32.load - (i32.const 40) - ) - (i32.shr_u - (get_local $x) - (i32.const 24) - ) - ) - ) - (i32.const 24) - ) - ) - ) (func $___muldsi3 (param $$a i32) (param $$b i32) (result i32) (local $$8 i32) (local $$6 i32) @@ -29578,7 +29484,7 @@ (set_local $$_0$0 (i32.shr_u (get_local $$n_sroa_1_4_extract_trunc) - (call $_llvm_cttz_i32 + (i32.ctz (get_local $$d_sroa_1_4_extract_trunc) ) ) @@ -30053,7 +29959,7 @@ ) (block (set_local $$78 - (call $_llvm_cttz_i32 + (i32.ctz (get_local $$d_sroa_0_0_extract_trunc) ) ) diff --git a/test/min.asm.js b/test/min.asm.js index ed5d186f5..b72002f97 100644 --- a/test/min.asm.js +++ b/test/min.asm.js @@ -7,6 +7,7 @@ function (global, env, buffer) { var fr = global.Math.fround; var tDP = env.tempDoublePtr | 0; + var ctz32 = env._llvm_cttz_i32; var h8 = new global.Int8Array(buffer); var h16 = new global.Int16Array(buffer); @@ -36,6 +37,9 @@ function (global, env, buffer) { (h32[tDP >> 2] = i, +hF32[tDP >> 2]); // i32->f32, no fround (hF32[tDP >> 2] = f, h32[tDP >> 2] | 0); // f32->i32 } + function ctzzzz() { + return ctz32(0x1234) | 0; + } return { floats: floats }; } diff --git a/test/min.fromasm b/test/min.fromasm index 199056e42..f4c170b62 100644 --- a/test/min.fromasm +++ b/test/min.fromasm @@ -42,4 +42,11 @@ (get_local $f) ) ) + (func $ctzzzz (result i32) + (return + (i32.ctz + (i32.const 4660) + ) + ) + ) ) diff --git a/test/min.fromasm.imprecise b/test/min.fromasm.imprecise index 199056e42..f4c170b62 100644 --- a/test/min.fromasm.imprecise +++ b/test/min.fromasm.imprecise @@ -42,4 +42,11 @@ (get_local $f) ) ) + (func $ctzzzz (result i32) + (return + (i32.ctz + (i32.const 4660) + ) + ) + ) ) |