summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h13
-rw-r--r--src/emscripten-optimizer/parser.cpp1
-rw-r--r--src/emscripten-optimizer/parser.h1
-rw-r--r--test/emcc_hello_world.asm.js12
-rw-r--r--test/emcc_hello_world.fromasm98
-rw-r--r--test/emcc_hello_world.fromasm.imprecise98
-rw-r--r--test/min.asm.js4
-rw-r--r--test/min.fromasm7
-rw-r--r--test/min.fromasm.imprecise7
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)
+ )
+ )
+ )
)