diff options
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 86 | ||||
-rw-r--r-- | src/passes/pass.cpp | 10 | ||||
-rw-r--r-- | src/passes/passes.h | 1 | ||||
-rw-r--r-- | test/passes/O4_disable-bulk-memory.txt | 2 | ||||
-rw-r--r-- | test/passes/simplify-globals-optimizing_enable-mutable-globals.txt | 167 | ||||
-rw-r--r-- | test/passes/simplify-globals-optimizing_enable-mutable-globals.wast | 129 | ||||
-rw-r--r-- | test/passes/simplify-globals_enable-mutable-globals.txt | 101 | ||||
-rw-r--r-- | test/passes/simplify-globals_enable-mutable-globals.wast | 62 | ||||
-rw-r--r-- | test/unit.fromasm | 19 | ||||
-rw-r--r-- | test/unit.fromasm.clamp | 19 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 19 | ||||
-rw-r--r-- | test/wasm2js/conversions-modified.2asm.js.opt | 2 |
12 files changed, 550 insertions, 67 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index fce9df964..88f27f8be 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -22,13 +22,21 @@ // * If an immutable global is a copy of another, use the earlier one, // to allow removal of the copies later. // * Apply the constant values of immutable globals. +// * Apply the constant values of previous global.sets, in a linear +// execution trace. // // Some globals may not have uses after these changes, which we leave // to other passes to optimize. // +// This pass has a "optimize" variant (similar to inlining and DAE) +// that also runs general function optimizations where we managed to replace +// a constant value. That is helpful as such a replacement often opens up +// further optimization opportunities. +// #include <atomic> +#include "ir/effects.h" #include "ir/utils.h" #include "pass.h" #include "wasm-builder.h" @@ -84,26 +92,73 @@ private: }; struct ConstantGlobalApplier - : public WalkerPass<PostWalker<ConstantGlobalApplier>> { + : public WalkerPass< + LinearExecutionWalker<ConstantGlobalApplier, + UnifiedExpressionVisitor<ConstantGlobalApplier>>> { bool isFunctionParallel() override { return true; } - ConstantGlobalApplier(NameSet* constantGlobals) - : constantGlobals(constantGlobals) {} + ConstantGlobalApplier(NameSet* constantGlobals, bool optimize) + : constantGlobals(constantGlobals), optimize(optimize) {} ConstantGlobalApplier* create() override { - return new ConstantGlobalApplier(constantGlobals); + return new ConstantGlobalApplier(constantGlobals, optimize); } - void visitGlobalGet(GlobalGet* curr) { - if (constantGlobals->count(curr->name)) { - auto* global = getModule()->getGlobal(curr->name); - assert(global->init->is<Const>()); - replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); + void visitExpression(Expression* curr) { + if (auto* set = curr->dynCast<GlobalSet>()) { + if (auto* c = set->value->dynCast<Const>()) { + currConstantGlobals[set->name] = c->value; + } else { + currConstantGlobals.erase(set->name); + } + return; + } else if (auto* get = curr->dynCast<GlobalGet>()) { + // Check if the global is known to be constant all the time. + if (constantGlobals->count(get->name)) { + auto* global = getModule()->getGlobal(get->name); + assert(global->init->is<Const>()); + replaceCurrent(ExpressionManipulator::copy(global->init, *getModule())); + replaced = true; + return; + } + // Check if the global has a known value in this linear trace. + auto iter = currConstantGlobals.find(get->name); + if (iter != currConstantGlobals.end()) { + Builder builder(*getModule()); + replaceCurrent(builder.makeConst(iter->second)); + replaced = true; + } + return; + } + // Otherwise, invalidate if we need to. + EffectAnalyzer effects(getPassOptions()); + effects.visit(curr); + assert(effects.globalsWritten.empty()); // handled above + if (effects.calls) { + currConstantGlobals.clear(); + } + } + + static void doNoteNonLinear(ConstantGlobalApplier* self, Expression** currp) { + self->currConstantGlobals.clear(); + } + + void visitFunction(Function* curr) { + if (replaced && optimize) { + PassRunner runner(getModule(), getPassRunner()->options); + runner.setIsNested(true); + runner.addDefaultFunctionOptimizationPasses(); + runner.runOnFunction(curr); } } private: NameSet* constantGlobals; + bool optimize; + bool replaced = false; + + // The globals currently constant in the linear trace. + std::map<Name, Literal> currConstantGlobals; }; } // anonymous namespace @@ -113,6 +168,9 @@ struct SimplifyGlobals : public Pass { Module* module; GlobalInfoMap map; + bool optimize; + + SimplifyGlobals(bool optimize = false) : optimize(optimize) {} void run(PassRunner* runner_, Module* module_) override { runner = runner_; @@ -214,12 +272,14 @@ struct SimplifyGlobals : public Pass { constantGlobals.insert(global->name); } } - if (!constantGlobals.empty()) { - ConstantGlobalApplier(&constantGlobals).run(runner, module); - } + ConstantGlobalApplier(&constantGlobals, optimize).run(runner, module); } }; -Pass* createSimplifyGlobalsPass() { return new SimplifyGlobals(); } +Pass* createSimplifyGlobalsPass() { return new SimplifyGlobals(false); } + +Pass* createSimplifyGlobalsOptimizingPass() { + return new SimplifyGlobals(true); +} } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index daa575c6d..7d17510fc 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -267,6 +267,10 @@ void PassRegistry::registerPasses() { registerPass("simplify-globals", "miscellaneous globals-related optimizations", createSimplifyGlobalsPass); + registerPass("simplify-globals-optimizing", + "miscellaneous globals-related optimizations, and optimizes " + "where we replaced global.gets with constants", + createSimplifyGlobalsOptimizingPass); registerPass("simplify-locals", "miscellaneous locals-related optimizations", createSimplifyLocalsPass); @@ -416,7 +420,11 @@ void PassRunner::addDefaultGlobalOptimizationPostPasses() { // optimizations show more functions as duplicate add("duplicate-function-elimination"); add("duplicate-import-elimination"); - add("simplify-globals"); + if (options.optimizeLevel >= 2 || options.shrinkLevel >= 2) { + add("simplify-globals-optimizing"); + } else { + add("simplify-globals"); + } add("remove-unused-module-elements"); add("memory-packing"); // may allow more inlining/dae/etc., need --converge for that diff --git a/src/passes/passes.h b/src/passes/passes.h index 115e9bab6..6342ea15b 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -92,6 +92,7 @@ Pass* createRedundantSetEliminationPass(); Pass* createSafeHeapPass(); Pass* createSimplifyLocalsPass(); Pass* createSimplifyGlobalsPass(); +Pass* createSimplifyGlobalsOptimizingPass(); Pass* createSimplifyLocalsNoNestingPass(); Pass* createSimplifyLocalsNoTeePass(); Pass* createSimplifyLocalsNoStructurePass(); diff --git a/test/passes/O4_disable-bulk-memory.txt b/test/passes/O4_disable-bulk-memory.txt index 455d8101d..2f354eb59 100644 --- a/test/passes/O4_disable-bulk-memory.txt +++ b/test/passes/O4_disable-bulk-memory.txt @@ -1284,7 +1284,7 @@ (i32.const 104) ) (global.set $global$1 - (global.get $global$0) + (i32.const 104) ) ) (func $null (; 12 ;) (; has Stack IR ;) (type $0) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt new file mode 100644 index 000000000..3511927ff --- /dev/null +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt @@ -0,0 +1,167 @@ +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 i32 (global.get $g1)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + ) +) +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 i32 (global.get $g1)) + (global $g3 i32 (global.get $g2)) + (global $g4 i32 (global.get $g3)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + (drop + (global.get $g1) + ) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 i32 (global.get $g1)) +) +(module + (type $FUNCSIG$v (func)) + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (global.set $g2 + (unreachable) + ) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 (mut i32) (global.get $g1)) + (export "global-2" (global $g2)) +) +(module + (type $FUNCSIG$v (func)) + (global $g1 i32 (i32.const 1)) + (global $g2 i32 (i32.const 1)) + (global $g3 f64 (f64.const -3.4)) + (global $g4 f64 (f64.const -2.8)) + (global $g5 i32 (i32.const 2)) + (global $g6 i32 (i32.const 2)) + (global $g7 i32 (i32.const 3)) + (global $g8 i32 (i32.const 3)) + (global $g9 i32 (i32.const 4)) + (global $ga (mut i32) (i32.const 4)) + (global $gb (mut i32) (i32.const 5)) + (global $gc i32 (i32.const 5)) + (func $foo (; 0 ;) (type $FUNCSIG$v) + (global.set $ga + (i32.const 6) + ) + (global.set $gb + (i32.const 7) + ) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $0) + ) + (if + (local.get $0) + (return + (i32.const 0) + ) + ) + (if + (local.tee $0 + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (return + (i32.const 1) + ) + ) + (global.set $g1 + (i32.const 200) + ) + (global.set $g2 + (local.get $0) + ) + (i32.add + (global.get $g2) + (i32.const 200) + ) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $0) + ) + (i32.add + (global.get $g2) + (i32.const 200) + ) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (drop + (call $no + (i32.const 200) + ) + ) + (global.get $g1) + ) + (func $no2 (; 1 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g1 + (local.get $x) + ) + (global.get $g1) + ) + (func $yes (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $0) + ) + (i32.const 100) + ) +) diff --git a/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast new file mode 100644 index 000000000..f8a099e95 --- /dev/null +++ b/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast @@ -0,0 +1,129 @@ +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo + (drop (global.get $g1)) + (drop (global.get $g2)) + ) +) +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (global $g3 (mut i32) (global.get $g2)) + (global $g4 (mut i32) (global.get $g3)) + (func $foo + (drop (global.get $g1)) + (drop (global.get $g2)) + (drop (global.get $g3)) + (drop (global.get $g4)) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 (mut i32) (global.get $g1)) +) +(module + (import "env" "global-1" (global $g1 i32)) + (global $g2 (mut i32) (global.get $g1)) + (func $foo + (global.set $g2 (unreachable)) + ) +) +(module + (import "env" "global-1" (global $g1 (mut i32))) + (global $g2 (mut i32) (global.get $g1)) + (export "global-2" (global $g2)) +) +(module + (global $g1 i32 (i32.const 1)) + (global $g2 i32 (global.get $g1)) + (global $g3 f64 (f64.const -3.4)) + (global $g4 (mut f64) (f64.const -2.8)) + (global $g5 i32 (i32.const 2)) + (global $g6 (mut i32) (global.get $g5)) + (global $g7 (mut i32) (i32.const 3)) + (global $g8 i32 (global.get $g7)) + (global $g9 i32 (i32.const 4)) + (global $ga (mut i32) (global.get $g9)) + (global $gb (mut i32) (i32.const 5)) + (global $gc i32 (global.get $gb)) + (func $foo + (drop (global.get $g1)) + (drop (global.get $g2)) + (drop (global.get $g3)) + (drop (global.get $g4)) + (drop (global.get $g5)) + (drop (global.get $g6)) + (drop (global.get $g7)) + (drop (global.get $g8)) + (drop (global.get $g9)) + (drop (global.get $ga)) + (drop (global.get $gb)) + (drop (global.get $gc)) + (global.set $ga (i32.const 6)) + (global.set $gb (i32.const 7)) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (if (local.get $x) (return (i32.const 0))) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if (local.get $x) (return (i32.const 1))) + (global.set $g1 (i32.const 200)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (i32.add + (global.get $g1) + (global.get $g1) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $no (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (drop (call $no (i32.const 200))) ;; invalidate + (global.get $g1) + ) + (func $no2 (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g1 (local.get $x)) ;; invalidate + (global.get $g1) + ) + (func $yes (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) ;; almost invalidate + (global.get $g1) + ) +) + diff --git a/test/passes/simplify-globals_enable-mutable-globals.txt b/test/passes/simplify-globals_enable-mutable-globals.txt index 346161f14..e0971742b 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.txt +++ b/test/passes/simplify-globals_enable-mutable-globals.txt @@ -110,3 +110,104 @@ ) ) ) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (if + (local.get $x) + (return + (i32.const 0) + ) + ) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if + (local.get $x) + (return + (i32.const 1) + ) + ) + (global.set $g1 + (i32.const 200) + ) + (global.set $g2 + (local.get $x) + ) + (local.set $x + (i32.add + (i32.const 200) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (local.set $x + (i32.add + (i32.add + (i32.const 100) + (i32.const 100) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $no (; 0 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (drop + (call $no + (i32.const 200) + ) + ) + (global.get $g1) + ) + (func $no2 (; 1 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g1 + (local.get $x) + ) + (global.get $g1) + ) + (func $yes (; 2 ;) (type $FUNCSIG$ii) (param $x i32) (result i32) + (global.set $g1 + (i32.const 100) + ) + (global.set $g2 + (local.get $x) + ) + (i32.const 100) + ) +) diff --git a/test/passes/simplify-globals_enable-mutable-globals.wast b/test/passes/simplify-globals_enable-mutable-globals.wast index 14038769a..f8a099e95 100644 --- a/test/passes/simplify-globals_enable-mutable-globals.wast +++ b/test/passes/simplify-globals_enable-mutable-globals.wast @@ -64,4 +64,66 @@ (global.set $gb (i32.const 7)) ) ) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (if (local.get $x) (return (i32.const 0))) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (if (local.get $x) (return (i32.const 1))) + (global.set $g1 (i32.const 200)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (global.get $g1) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $f (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) + (local.set $x + (i32.add + (i32.add + (global.get $g1) + (global.get $g1) + ) + (global.get $g2) + ) + ) + (local.get $x) + ) +) +(module + (global $g1 (mut i32) (i32.const 1)) + (global $g2 (mut i32) (i32.const 1)) + (func $no (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (drop (call $no (i32.const 200))) ;; invalidate + (global.get $g1) + ) + (func $no2 (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g1 (local.get $x)) ;; invalidate + (global.get $g1) + ) + (func $yes (param $x i32) (result i32) + (global.set $g1 (i32.const 100)) + (global.set $g2 (local.get $x)) ;; almost invalidate + (global.get $g1) + ) +) diff --git a/test/unit.fromasm b/test/unit.fromasm index b56f3e4fb..1080e7092 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -89,15 +89,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 10 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -529,7 +520,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 36 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1134,13 +1125,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp index 3f4282103..b98fe30c6 100644 --- a/test/unit.fromasm.clamp +++ b/test/unit.fromasm.clamp @@ -87,15 +87,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -577,7 +568,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 37 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1177,13 +1168,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index fd444c505..04528ad47 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -85,15 +85,6 @@ (f64.const -3.4) ) ) - (if - (f64.gt - (f64.const 0) - (f64.const 0) - ) - (return - (f64.const 5.6) - ) - ) (f64.const 1.2) ) (func $doubleCompares (; 9 ;) (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64) @@ -517,7 +508,7 @@ (global.set $Int (i32.const 30) ) - (global.get $Int) + (i32.const 30) ) (func $usesGlobalSet2 (; 35 ;) (; has Stack IR ;) (result i32) (global.set $Int @@ -1112,13 +1103,7 @@ (global.set $Int (i32.const 1) ) - (i32.add - (i32.and - (global.get $Int) - (i32.const 7) - ) - (i32.const 16) - ) + (i32.const 17) ) ) (call $emscripten_log) diff --git a/test/wasm2js/conversions-modified.2asm.js.opt b/test/wasm2js/conversions-modified.2asm.js.opt index 418589d01..fceed0c6c 100644 --- a/test/wasm2js/conversions-modified.2asm.js.opt +++ b/test/wasm2js/conversions-modified.2asm.js.opt @@ -133,7 +133,7 @@ function asmFunc(global, env, buffer) { function legalstub$1($0) { i64toi32_i32$HIGH_BITS = 0; - setTempRet0(i64toi32_i32$HIGH_BITS | 0); + setTempRet0(0); return $0; } |