Commit 085bdae2 by Eric Holk

Subzero, Wasm: Link and run torture tests; bug fixes.

This modifies the torture test script to actually link and run the tests in addition to just translating them. It includes a number of bug fixes as well, particularly in the handling of boolean values. There is some cleanup of memory address handling, and in many cases it can avoid generating useless address computations. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4369 R=jpp@chromium.org Review URL: https://codereview.chromium.org/1890283002 .
parent dd6dcfaf
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
# that should be removed. # that should be removed.
./wasm-install/bin/emscripten/emcc "$1" -s BINARYEN=1 \ ./wasm-install/bin/emscripten/emcc "$1" -s BINARYEN=1 \
-s 'BINARYEN_METHOD="native-wasm"' -O2 && \ -s 'BINARYEN_METHOD="native-wasm"' -O2 \
--em-config wasm-install/emscripten_config_vanilla && \
./wasm-install/bin/sexpr-wasm a.out.wast -o a.out.wasm && \ ./wasm-install/bin/sexpr-wasm a.out.wast -o a.out.wasm && \
./pnacl-sz a.out.wasm -o a.out.o -filetype=obj -O2 && \ ./pnacl-sz a.out.wasm -o a.out.o -filetype=obj -O2 && \
clang -m32 a.out.o runtime/wasm-runtime.c -g clang -m32 a.out.o runtime/wasm-runtime.c -g
#!/bin/bash #!/bin/bash
BUILDID=4915 BUILDID=5430
BUILD_PATH=https://storage.googleapis.com/wasm-llvm/builds/git BUILD_PATH=https://storage.googleapis.com/wasm-llvm/builds/git
wget -O - /wasm-torture-s-$BUILDID.tbz2 \ wget -O - /wasm-torture-s-$BUILDID.tbz2 \
...@@ -11,3 +11,7 @@ wget -O - $BUILD_PATH/wasm-torture-s2wasm-sexpr-wasm-$BUILDID.tbz2 \ ...@@ -11,3 +11,7 @@ wget -O - $BUILD_PATH/wasm-torture-s2wasm-sexpr-wasm-$BUILDID.tbz2 \
wget -O - $BUILD_PATH/wasm-binaries-$BUILDID.tbz2 \ wget -O - $BUILD_PATH/wasm-binaries-$BUILDID.tbz2 \
| tar xj | tar xj
wget -O - \
$BUILD_PATH/wasm-torture-/b/build/slave/linux/build/src/src/work/wasm-install/emscripten_config_vanilla-$BUILDID.tbz2 \
| tar xj
...@@ -11,19 +11,68 @@ ...@@ -11,19 +11,68 @@
import glob import glob
import os import os
import shutil
import sys import sys
success_count = 0 IGNORED_TESTS = [
fail_count = 0 'loop-2f.c.wasm', # mmap not in MVP
failures = [] 'loop-2g.c.wasm', # mmap not in MVP
'960521-1.c.wasm', # sbrk not in MVP
'pr36765.c.wasm', # __builtin_malloc not allowed
'pr24716.c.wasm', # infinite loop
'vla-dealloc-1.c.wasm', # infinite loop
'20040811-1.c.wasm', # infinite loop
'961125-1.c.wasm', # infinite loop
'980506-1.c.wasm', # infinite loop
'20070824-1.c.wasm', # infinite loop
'20140212-1.c.wasm', # infinite loop
'pr59014.c.wasm', # infinite loop
'pr58277-2.c.wasm', # infinite loop
'pr43560.c.wasm', # infinite loop
'20000818-1.c.wasm', # infinite loop
'20010409-1.c.wasm', # infinite loop
'loop-7.c.wasm', # infinite loop
'pr34415.c.wasm', # infinite loop
'20011126-2.c.wasm', # infinite loop
'postmod-1.c.wasm', # infinite loop
'pr17133.c.wasm', # infinite loop
'20021024-1.c.wasm', # infinite loop
'pr15296.c.wasm', # infinite loop
'990524-1.c.wasm', # infinite loop
'loop-12.c.wasm', # infinite loop
'961125-1.c.wasm', # infinite loop
]
OUT_DIR = "./build/wasm-torture"
compile_count = 0
compile_failures = []
run_count = 0
run_failures = []
def run_test(test_file, verbose=False): def run_test(test_file, verbose=False):
global success_count global compile_count
global fail_count global compile_failures
global run_count
global run_failures
global OUT_DIR
global IGNORED_TESTS
test_name = os.path.basename(test_file)
obj_file = os.path.join(OUT_DIR, test_name + ".o")
exe_file = os.path.join(OUT_DIR, test_name + ".exe")
if not verbose and test_name in IGNORED_TESTS:
print("\033[1;34mSkipping {}\033[1;m".format(test_file))
return
cmd = """LD_LIBRARY_PATH=../../../../v8/out/native/lib.target ./pnacl-sz \ cmd = """LD_LIBRARY_PATH=../../../../v8/out/native/lib.target ./pnacl-sz \
-filetype=asm -target=x8632 {} -threads=0 -O2 \ -filetype=obj -target=x8632 {} -threads=0 -O2 \
-verbose=wasm""".format(test_file) -verbose=wasm -o {}""".format(test_file, obj_file)
if not verbose: if not verbose:
cmd += " &> /dev/null" cmd += " &> /dev/null"
...@@ -31,13 +80,24 @@ def run_test(test_file, verbose=False): ...@@ -31,13 +80,24 @@ def run_test(test_file, verbose=False):
sys.stdout.write(test_file + " ..."); sys.stdout.write(test_file + " ...");
status = os.system(cmd); status = os.system(cmd);
if status != 0: if status != 0:
fail_count += 1 print('\033[1;31m[compile fail]\033[1;m')
print('\033[1;31m[fail]\033[1;m') compile_failures.append(test_file)
failures.append(test_file)
else: else:
success_count += 1 compile_count += 1
print('\033[1;32m[ok]\033[1;m')
# Try to link and run the program.
cmd = "clang -g -m32 {} -o {} ./runtime/wasm-runtime.c".format(obj_file,
exe_file)
if os.system(cmd) == 0:
if os.system(exe_file) == 0:
run_count += 1
print('\033[1;32m[ok]\033[1;m')
else:
run_failures.append(test_file)
print('\033[1;33m[run fail]\033[1;m')
else:
run_failures.append(test_file)
print('\033[1;33m[run fail]\033[1;m')
verbose = False verbose = False
...@@ -45,13 +105,29 @@ if len(sys.argv) > 1: ...@@ -45,13 +105,29 @@ if len(sys.argv) > 1:
test_files = sys.argv[1:] test_files = sys.argv[1:]
verbose = True verbose = True
else: else:
test_files = glob.glob("./torture-s2wasm-sexpr-wasm/*.wasm") test_files = glob.glob("./emwasm-torture-out/*.wasm")
if os.path.exists(OUT_DIR):
shutil.rmtree(OUT_DIR)
os.mkdir(OUT_DIR)
for test_file in test_files: for test_file in test_files:
run_test(test_file, verbose) run_test(test_file, verbose)
if len(failures) > 0: if len(compile_failures) > 0:
print("Failures:") print
for f in failures: print("Compilation failures:")
print("=====================\n")
for f in compile_failures:
print(" \033[1;31m" + f + "\033[1;m") print(" \033[1;31m" + f + "\033[1;m")
print("{} / {} tests passed".format(success_count, success_count + fail_count))
if len(run_failures) > 0:
print
print("Run failures:")
print("=============\n")
for f in run_failures:
print(" \033[1;33m" + f + "\033[1;m")
print("\n\033[1;32m{}\033[1;m / \033[1;33m{}\033[1;m / {} tests passed"
.format(run_count, compile_count - run_count,
run_count + len(compile_failures) + len(run_failures)))
...@@ -13,9 +13,12 @@ ...@@ -13,9 +13,12 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
extern char WASM_MEMORY[]; extern char WASM_MEMORY[];
...@@ -27,6 +30,11 @@ void env$$abort() { ...@@ -27,6 +30,11 @@ void env$$abort() {
void env$$_abort() { env$$abort(); } void env$$_abort() { env$$abort(); }
void env$$exit(int Status) {
exit(Status);
}
void env$$_exit(int Status) { env$$exit(Status); }
#define UNIMPLEMENTED(f) \ #define UNIMPLEMENTED(f) \
void env$$##f() { \ void env$$##f() { \
fprintf(stderr, "Unimplemented: " #f "\n"); \ fprintf(stderr, "Unimplemented: " #f "\n"); \
...@@ -34,13 +42,36 @@ void env$$_abort() { env$$abort(); } ...@@ -34,13 +42,36 @@ void env$$_abort() { env$$abort(); }
} }
UNIMPLEMENTED(sbrk) UNIMPLEMENTED(sbrk)
UNIMPLEMENTED(setjmp)
UNIMPLEMENTED(longjmp)
UNIMPLEMENTED(__assert_fail)
UNIMPLEMENTED(__builtin_malloc)
UNIMPLEMENTED(__builtin_apply)
UNIMPLEMENTED(__builtin_apply_args)
UNIMPLEMENTED(pthread_cleanup_push) UNIMPLEMENTED(pthread_cleanup_push)
UNIMPLEMENTED(pthread_cleanup_pop) UNIMPLEMENTED(pthread_cleanup_pop)
UNIMPLEMENTED(pthread_self) UNIMPLEMENTED(pthread_self)
UNIMPLEMENTED(abs)
UNIMPLEMENTED(__floatditf)
UNIMPLEMENTED(__floatsitf)
UNIMPLEMENTED(__fixtfdi)
UNIMPLEMENTED(__fixtfsi)
UNIMPLEMENTED(__fixsfti)
UNIMPLEMENTED(__netf2)
UNIMPLEMENTED(__getf2)
UNIMPLEMENTED(__eqtf2)
UNIMPLEMENTED(__lttf2)
UNIMPLEMENTED(__addtf3)
UNIMPLEMENTED(__subtf3)
UNIMPLEMENTED(__divtf3)
UNIMPLEMENTED(__multf3)
UNIMPLEMENTED(__multi3)
UNIMPLEMENTED(__lock) UNIMPLEMENTED(__lock)
UNIMPLEMENTED(__unlock) UNIMPLEMENTED(__unlock)
UNIMPLEMENTED(__syscall6) UNIMPLEMENTED(__syscall6)
UNIMPLEMENTED(__syscall20)
UNIMPLEMENTED(__syscall140) UNIMPLEMENTED(__syscall140)
UNIMPLEMENTED(__syscall192)
void *wasmPtr(int Index) { void *wasmPtr(int Index) {
// TODO (eholk): get the mask from the WASM file. // TODO (eholk): get the mask from the WASM file.
...@@ -50,12 +81,12 @@ void *wasmPtr(int Index) { ...@@ -50,12 +81,12 @@ void *wasmPtr(int Index) {
return WASM_MEMORY + Index; return WASM_MEMORY + Index;
} }
extern int __szwasm_main(int, char **); extern int __szwasm_main(int, const char **);
#define WASM_REF(Type, Index) ((Type *)wasmPtr(Index)) #define WASM_REF(Type, Index) ((Type *)wasmPtr(Index))
#define WASM_DEREF(Type, Index) (*WASM_REF(Type, Index)) #define WASM_DEREF(Type, Index) (*WASM_REF(Type, Index))
int main(int argc, char **argv) { return __szwasm_main(argc, argv); } int main(int argc, const char **argv) { return __szwasm_main(argc, argv); }
/// sys_write /// sys_write
int env$$__syscall4(int Which, int VarArgs) { int env$$__syscall4(int Which, int VarArgs) {
...@@ -66,6 +97,18 @@ int env$$__syscall4(int Which, int VarArgs) { ...@@ -66,6 +97,18 @@ int env$$__syscall4(int Which, int VarArgs) {
return write(Fd, WASM_REF(char *, Buffer), Length); return write(Fd, WASM_REF(char *, Buffer), Length);
} }
/// sys_open
int env$$__syscall5(int Which, int VarArgs) {
int WasmPath = WASM_DEREF(int, VarArgs);
int Flags = WASM_DEREF(int, VarArgs + 4);
int Mode = WASM_DEREF(int, VarArgs + 8);
const char *Path = WASM_REF(char, WasmPath);
fprintf(stderr, "sys_open(%s, %d, %d)\n", Path, Flags, Mode);
return open(Path, Flags, Mode);
}
/// sys_ioctl /// sys_ioctl
int env$$__syscall54(int A, int B) { int env$$__syscall54(int A, int B) {
int Fd = WASM_DEREF(int, B + 0 * sizeof(int)); int Fd = WASM_DEREF(int, B + 0 * sizeof(int));
......
...@@ -266,8 +266,9 @@ void Cfg::fixPhiNodes() { ...@@ -266,8 +266,9 @@ void Cfg::fixPhiNodes() {
void Cfg::computeInOutEdges() { void Cfg::computeInOutEdges() {
// Compute the out-edges. // Compute the out-edges.
for (CfgNode *Node : Nodes) for (CfgNode *Node : Nodes) {
Node->computeSuccessors(); Node->computeSuccessors();
}
// Prune any unreachable nodes before computing in-edges. // Prune any unreachable nodes before computing in-edges.
SizeT NumNodes = getNumNodes(); SizeT NumNodes = getNumNodes();
......
...@@ -28,7 +28,7 @@ namespace Ice { ...@@ -28,7 +28,7 @@ namespace Ice {
// Adds an instruction to either the Phi list or the regular instruction list. // Adds an instruction to either the Phi list or the regular instruction list.
// Validates that all Phis are added before all regular instructions. // Validates that all Phis are added before all regular instructions.
void CfgNode::appendInst(Inst *Instr, bool AllowPhisAnywhere) { void CfgNode::appendInst(Inst *Instr) {
++InstCountEstimate; ++InstCountEstimate;
if (BuildDefs::wasm()) { if (BuildDefs::wasm()) {
...@@ -41,7 +41,7 @@ void CfgNode::appendInst(Inst *Instr, bool AllowPhisAnywhere) { ...@@ -41,7 +41,7 @@ void CfgNode::appendInst(Inst *Instr, bool AllowPhisAnywhere) {
} }
if (auto *Phi = llvm::dyn_cast<InstPhi>(Instr)) { if (auto *Phi = llvm::dyn_cast<InstPhi>(Instr)) {
if (!AllowPhisAnywhere && !Insts.empty()) { if (!Insts.empty()) {
Func->setError("Phi instruction added to the middle of a block"); Func->setError("Phi instruction added to the middle of a block");
return; return;
} }
...@@ -84,6 +84,7 @@ void CfgNode::computePredecessors() { ...@@ -84,6 +84,7 @@ void CfgNode::computePredecessors() {
void CfgNode::computeSuccessors() { void CfgNode::computeSuccessors() {
OutEdges.clear(); OutEdges.clear();
InEdges.clear(); InEdges.clear();
assert(!Insts.empty());
OutEdges = Insts.rbegin()->getTerminatorEdges(); OutEdges = Insts.rbegin()->getTerminatorEdges();
} }
......
...@@ -76,7 +76,7 @@ public: ...@@ -76,7 +76,7 @@ public:
/// @{ /// @{
InstList &getInsts() { return Insts; } InstList &getInsts() { return Insts; }
PhiList &getPhis() { return Phis; } PhiList &getPhis() { return Phis; }
void appendInst(Inst *Instr, bool AllowPhisAnywhere = false); void appendInst(Inst *Instr);
void renumberInstructions(); void renumberInstructions();
/// Rough and generally conservative estimate of the number of instructions in /// Rough and generally conservative estimate of the number of instructions in
/// the block. It is updated when an instruction is added, but not when /// the block. It is updated when an instruction is added, but not when
......
...@@ -58,6 +58,8 @@ using v8::internal::wasm::DecodeWasmModule; ...@@ -58,6 +58,8 @@ using v8::internal::wasm::DecodeWasmModule;
#define LOG(Expr) log([&](Ostream & out) { Expr; }) #define LOG(Expr) log([&](Ostream & out) { Expr; })
namespace { namespace {
// 64KB
const uint32_t WASM_PAGE_SIZE = 64 << 10;
std::string toStdString(WasmName Name) { std::string toStdString(WasmName Name) {
return std::string(Name.name, Name.length); return std::string(Name.name, Name.length);
...@@ -466,7 +468,7 @@ public: ...@@ -466,7 +468,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Ne, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Ne, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32Eq: case kExprI32Eq:
...@@ -475,7 +477,7 @@ public: ...@@ -475,7 +477,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Eq, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Eq, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32LtS: case kExprI32LtS:
...@@ -484,7 +486,7 @@ public: ...@@ -484,7 +486,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Slt, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Slt, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32LeS: case kExprI32LeS:
...@@ -493,7 +495,7 @@ public: ...@@ -493,7 +495,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Sle, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Sle, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32GeU: case kExprI32GeU:
...@@ -502,7 +504,7 @@ public: ...@@ -502,7 +504,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Uge, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Uge, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32LeU: case kExprI32LeU:
...@@ -511,7 +513,7 @@ public: ...@@ -511,7 +513,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Ule, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Ule, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32LtU: case kExprI32LtU:
...@@ -520,7 +522,7 @@ public: ...@@ -520,7 +522,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Ult, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Ult, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32GeS: case kExprI32GeS:
...@@ -529,7 +531,7 @@ public: ...@@ -529,7 +531,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
} }
case kExprI32GtS: case kExprI32GtS:
case kExprI64GtS: { case kExprI64GtS: {
...@@ -537,7 +539,7 @@ public: ...@@ -537,7 +539,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprI32GtU: case kExprI32GtU:
...@@ -546,7 +548,7 @@ public: ...@@ -546,7 +548,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprF32Ne: case kExprF32Ne:
...@@ -555,7 +557,7 @@ public: ...@@ -555,7 +557,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
case kExprF32Le: case kExprF32Le:
...@@ -564,7 +566,7 @@ public: ...@@ -564,7 +566,7 @@ public:
Control()->appendInst( Control()->appendInst(
InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right));
Control()->appendInst( Control()->appendInst(
InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); InstCast::create(Func, InstCast::Zext, Dest, TmpDest));
break; break;
} }
default: default:
...@@ -585,7 +587,15 @@ public: ...@@ -585,7 +587,15 @@ public:
auto *Tmp = makeVariable(IceType_i1); auto *Tmp = makeVariable(IceType_i1);
Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input,
Ctx->getConstantInt32(0))); Ctx->getConstantInt32(0)));
Control()->appendInst(InstCast::create(Func, InstCast::Sext, Dest, Tmp)); Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp));
break;
}
case kExprI64Eqz: {
Dest = makeVariable(IceType_i32);
auto *Tmp = makeVariable(IceType_i1);
Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input,
Ctx->getConstantInt64(0)));
Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp));
break; break;
} }
case kExprF32Neg: { case kExprF32Neg: {
...@@ -673,7 +683,8 @@ public: ...@@ -673,7 +683,8 @@ public:
<< "\n"); << "\n");
auto *CondBool = makeVariable(IceType_i1); auto *CondBool = makeVariable(IceType_i1);
Ctrl->appendInst(InstCast::create(Func, InstCast::Trunc, CondBool, Cond)); Ctrl->appendInst(InstIcmp::create(Func, InstIcmp::Ne, CondBool, Cond,
Ctx->getConstantInt32(0)));
Ctrl->appendInst(InstBr::create(Func, CondBool, *TrueNode, *FalseNode)); Ctrl->appendInst(InstBr::create(Func, CondBool, *TrueNode, *FalseNode));
return OperandNode(nullptr); return OperandNode(nullptr);
...@@ -898,30 +909,45 @@ public: ...@@ -898,30 +909,45 @@ public:
} }
Operand *sanitizeAddress(Operand *Base, uint32_t Offset) { Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;
SizeT MemMask = MemSize - 1;
bool ConstZeroBase = false;
// first, add the index and the offset together. // first, add the index and the offset together.
if (0 != Offset) { if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
auto *Addr = makeVariable(IceType_i32); uint32_t RealOffset = Offset + ConstBase->getValue();
RealOffset &= MemMask;
Base = Ctx->getConstantInt32(RealOffset);
ConstZeroBase = (0 == RealOffset);
} else if (0 != Offset) {
auto *Addr = makeVariable(Ice::getPointerType());
auto *OffsetConstant = Ctx->getConstantInt32(Offset); auto *OffsetConstant = Ctx->getConstantInt32(Offset);
Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add, Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
Addr, Base, OffsetConstant)); Addr, Base, OffsetConstant));
Base = Addr; Base = Addr;
} }
SizeT MemSize = Module->module->min_mem_pages * (16 << 10); if (!llvm::dyn_cast<ConstantInteger32>(Base)) {
auto *WrappedAddr = makeVariable(IceType_i32); auto *ClampedAddr = makeVariable(Ice::getPointerType());
Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::Add, WrappedAddr, Base,
Ctx->getConstantInt32(MemSize)));
auto ClampedAddr = makeVariable(IceType_i32);
Control()->appendInst( Control()->appendInst(
InstArithmetic::create(Func, InstArithmetic::And, ClampedAddr, Base, InstArithmetic::create(Func, InstArithmetic::And, ClampedAddr, Base,
Ctx->getConstantInt32(MemSize - 1))); Ctx->getConstantInt32(MemSize - 1)));
Base = ClampedAddr;
}
auto RealAddr = Func->makeVariable(IceType_i32); Ice::Operand *RealAddr = nullptr;
auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY")); auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY"));
if (!ConstZeroBase) {
auto RealAddrV = Func->makeVariable(Ice::getPointerType());
Control()->appendInst(InstArithmetic::create( Control()->appendInst(InstArithmetic::create(
Func, InstArithmetic::Add, RealAddr, ClampedAddr, MemBase)); Func, InstArithmetic::Add, RealAddrV, Base, MemBase));
RealAddr = RealAddrV;
} else {
RealAddr = MemBase;
}
return RealAddr; return RealAddr;
} }
...@@ -1213,15 +1239,12 @@ void WasmTranslator::translate( ...@@ -1213,15 +1239,12 @@ void WasmTranslator::translate(
} }
// Pad the rest with zeros // Pad the rest with zeros
SizeT DataSize = Module->min_mem_pages * (64 << 10); SizeT DataSize = Module->min_mem_pages * WASM_PAGE_SIZE;
if (WritePtr < DataSize) { if (WritePtr < DataSize) {
WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create( WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
Globals.get(), DataSize - WritePtr)); Globals.get(), DataSize - WritePtr));
} }
WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
Globals.get(), Module->min_mem_pages * (64 << 10)));
Globals->push_back(WasmMemory); Globals->push_back(WasmMemory);
lowerGlobals(std::move(Globals)); lowerGlobals(std::move(Globals));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment