diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cases/i96shiftnon32_ta2.ll | 44 | ||||
-rw-r--r-- | tests/cases/i96shiftnon32_ta2.txt | 1 | ||||
-rw-r--r-- | tests/cases/legalizer_b_ta2.ll | 179 | ||||
-rw-r--r-- | tests/cases/legalizer_b_ta2.txt | 20 | ||||
-rw-r--r-- | tests/core/test_exceptions_alias.c | 15 | ||||
-rw-r--r-- | tests/core/test_exceptions_alias.out | 2 | ||||
-rw-r--r-- | tests/core/test_inlinejs3.in | 3 | ||||
-rw-r--r-- | tests/core/test_longjmp_throw.cpp | 38 | ||||
-rw-r--r-- | tests/core/test_longjmp_throw.out | 4 | ||||
-rw-r--r-- | tests/openal_playback.cpp | 44 | ||||
-rw-r--r-- | tests/poppler/utils/pdftoppm.cc | 5 | ||||
-rw-r--r-- | tests/test_core.py | 31 | ||||
-rw-r--r-- | tests/test_other.py | 27 |
13 files changed, 406 insertions, 7 deletions
diff --git a/tests/cases/i96shiftnon32_ta2.ll b/tests/cases/i96shiftnon32_ta2.ll new file mode 100644 index 00000000..55e84575 --- /dev/null +++ b/tests/cases/i96shiftnon32_ta2.ll @@ -0,0 +1,44 @@ +; ModuleID = '/tmp/tmpxFUbAg/test_emcc1.bc' +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" +target triple = "le32-unknown-nacl" + +%struct.c_s = type { i8, float, i32 } + +@.str = private unnamed_addr constant [12 x i8] c"RESULT: %d\0A\00", align 1 + +define internal fastcc void @f2(%struct.c_s* noalias nocapture sret %agg.result) nounwind { + %agg.result.1 = getelementptr inbounds %struct.c_s* %agg.result, i32 0, i32 1 + store float 0.000000e+00, float* %agg.result.1, align 4 + %agg.result.2 = getelementptr inbounds %struct.c_s* %agg.result, i32 0, i32 2 + store i32 43110, i32* %agg.result.2, align 4 + ret void +} + +define internal fastcc void @f1(%struct.c_s* nocapture %tp) nounwind { + %1 = alloca %struct.c_s, align 8 + call fastcc void @f2(%struct.c_s* sret %1) + %2 = bitcast %struct.c_s* %1 to i96* + %srcval1 = load i96* %2, align 8 + %small = trunc i96 %srcval1 to i64 + %large = zext i64 %small to i96 + %return = or i96 %srcval1, %large + %3 = lshr i96 %return, 4 + %4 = shl i96 %3, 2 + %5 = bitcast %struct.c_s* %tp to i96* + store i96 %4, i96* %5, align 4 + ret void +} + +define i32 @main() nounwind { + %t = alloca %struct.c_s, align 4 + %1 = getelementptr inbounds %struct.c_s* %t, i32 0, i32 1 + store float 1.000000e+00, float* %1, align 4 + call fastcc void @f1(%struct.c_s* %t) + %2 = getelementptr inbounds %struct.c_s* %t, i32 0, i32 2 + %3 = load i32* %2, align 4 + %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %3) nounwind + ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind + diff --git a/tests/cases/i96shiftnon32_ta2.txt b/tests/cases/i96shiftnon32_ta2.txt new file mode 100644 index 00000000..1e26a65f --- /dev/null +++ b/tests/cases/i96shiftnon32_ta2.txt @@ -0,0 +1 @@ +RESULT: 10777 diff --git a/tests/cases/legalizer_b_ta2.ll b/tests/cases/legalizer_b_ta2.ll new file mode 100644 index 00000000..a6214100 --- /dev/null +++ b/tests/cases/legalizer_b_ta2.ll @@ -0,0 +1,179 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" +target triple = "le32-unknown-nacl" + +@globaliz = global [300 x i8] zeroinitializer + +define i64 @retter(i64 %x) { + store i128 0, i128* bitcast ([300 x i8]* @globaliz to i128*), align 4 ; wipe it out + store i64 %x, i64* bitcast ([300 x i8]* @globaliz to i64*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + ret i64 7017280452245743464 +} + +define i32 @main() { +entry: + %buffer = alloca i8, i32 1000, align 4 + %bundled = bitcast i8* %buffer to i128* + store i128 8583909746840200552, i128* %bundled, align 4 ; hello world in there + call i32 (i8*)* @puts(i8* %buffer) + + %loaded = load i128* %bundled, align 4 ; save for later + + %backcast = bitcast i128* %bundled to i8* + call i32 (i8*)* @puts(i8* %backcast) + + %temp.buffer = bitcast i8* %buffer to [0 x i8]* + %buffer1 = getelementptr [0 x i8]* %temp.buffer, i32 0, i32 1 + %bundled1 = bitcast i8* %buffer1 to i128* + store i128 9862834326869351064, i128* %bundled1, align 1 ; unaligned + call i32 (i8*)* @puts(i8* %buffer) + +; shifts + %shifted = lshr i128 %loaded, 16 + store i128 %shifted, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + %shifted2 = lshr i128 %loaded, 32 + store i128 %shifted2, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + +; store %loaded, make sure has not been modified + store i128 %loaded, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + + %shifted3 = shl i128 %loaded, 8 + store i128 %shifted3, i128* %bundled, align 4 + store i8 113, i8* %buffer ; remove initial 0 ; 'q' + call i32 (i8*)* @puts(i8* %buffer) + +; trunc + %shifted4 = shl i128 %loaded, 64 + store i128 %shifted4, i128* %bundled, align 4 + %nonzero64 = trunc i128 %loaded to i64 ; remove initial zeros + %bundled64 = bitcast i128* %bundled to i64* + store i64 %nonzero64, i64* %bundled64, align 4 +; call i32 (i8*)* @puts(i8* %buffer) + + store i128 0, i128* %bundled, align 4 ; wipe it out + %small32 = trunc i128 %loaded to i32 + %buffer32 = bitcast i8* %buffer to i32* + store i32 %small32, i32* %buffer32, align 4 +; call i32 (i8*)* @puts(i8* %buffer) + + store i128 0, i128* %bundled, align 4 ; wipe it out + %small16 = trunc i128 %loaded to i16 + %buffer16 = bitcast i8* %buffer to i16* + store i16 %small16, i16* %buffer16, align 4 + call i32 (i8*)* @puts(i8* %buffer) + + store i128 0, i128* %bundled, align 4 ; wipe it out + %small64 = trunc i128 %loaded to i64 + %buffer64 = bitcast i8* %buffer to i64* + store i64 %small64, i64* %buffer64, align 4 + call i32 (i8*)* @puts(i8* %buffer) + +; zext + store i128 0, i128* %bundled, align 4 ; wipe it out + %pre32 = or i32 6382179, 0 + %big = zext i32 %pre32 to i128 + store i128 %big, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + + store i128 0, i128* %bundled, align 4 ; wipe it out + %pre64 = zext i32 1684366951 to i64 + %post64 = shl i64 %pre64, 32 + %big64 = or i64 %pre64, %post64 + %bigb = zext i64 %big64 to i128 + store i128 %bigb, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + +; or, and, xor + %ored = or i128 %loaded, 107752139522048 ; constant + store i128 %ored, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + + %ander = trunc i128 18402271027389267967 to i128 + %anded = and i128 %loaded, %ander ; variable + store i128 %anded, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + + %xored = xor i128 %loaded, 0 + store i128 %xored, i128* %bundled, align 4 + call i32 (i8*)* @puts(i8* %buffer) + +; unfolding + store i128 %loaded, i128* bitcast ([300 x i8]* @globaliz to i128*), align 4 + %loaded.short = load i96* bitcast ([300 x i8]* @globaliz to i96*), align 4 + store i128 0, i128* bitcast ([300 x i8]* @globaliz to i128*), align 4 + store i96 %loaded.short, i96* bitcast ([300 x i8]* @globaliz to i96*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + +; phi + %if = trunc i128 %ander to i1 + %first = trunc i128 %xored to i96 + br i1 %if, label %a17, label %a26 + +a17: + %second = trunc i128 %loaded to i96 + br label %a26 + +a26: + %a27 = phi i96 [ %first, %entry ], [ %second, %a17 ] + store i128 0, i128* %bundled, align 4 ; wipe it out + store i96 %a27, i96* bitcast ([300 x i8]* @globaliz to i96*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + +; phi with constants + br i1 %if, label %a17b, label %a26b + +a17b: + br label %a26b + +a26b: + %a27b = phi i64 [ 55, %a26 ], [ 57, %a17b ] + store i128 0, i128* %bundled, align 4 ; wipe it out + store i64 %a27b, i64* bitcast ([300 x i8]* @globaliz to i64*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + + store i128 %ored, i128* %bundled, align 4 + %iff = zext i1 %if to i64 + switch i64 %iff, label %a50 [ + i64 1, label %a30 + i64 0, label %a40 + ] + +a50: + store i128 %xored, i128* %bundled, align 4 + br label %a40 + +a30: + store i128 %anded, i128* %bundled, align 4 + br label %a40 + +a40: + call i32 (i8*)* @puts(i8* %buffer) + +; invoke return value + + %inv64 = invoke i64 @retter(i64 8174723217654970232) + to label %a100 unwind label %a111 + +a100: + store i128 0, i128* bitcast ([300 x i8]* @globaliz to i128*), align 4 ; wipe it out + store i64 %inv64, i64* bitcast ([300 x i8]* @globaliz to i64*), align 4 + call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*)) + br label %done + +a111: + %aaaa79 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + br label %done + +done: + ret i32 1 +} + +declare i32 @puts(i8*) +declare i32 @__gxx_personality_v0(...) +declare void @__cxa_throw(i32, i32, i32) ; for asm1, where exceptions are enabled but this test needs a throw to bring in lib stuff + diff --git a/tests/cases/legalizer_b_ta2.txt b/tests/cases/legalizer_b_ta2.txt new file mode 100644 index 00000000..27097159 --- /dev/null +++ b/tests/cases/legalizer_b_ta2.txt @@ -0,0 +1,20 @@ +hello, w +hello, w +h𚓓𓟈 +llo, w +o, w +hello, w +qhello, w +he +hello, w +cba +gfedgfed +hellon w +hello, w +hello, w +hello, w +hello, w +9 +hello, w +xwvutsrq +hgfedcba diff --git a/tests/core/test_exceptions_alias.c b/tests/core/test_exceptions_alias.c new file mode 100644 index 00000000..0c8cc37a --- /dev/null +++ b/tests/core/test_exceptions_alias.c @@ -0,0 +1,15 @@ +#define _POSIX_SOURCE +#include <locale.h> +#include <ctype.h> +#include <stdio.h> + +int main(void) { + try { + printf("*%i*\n", isdigit('0')); + printf("*%i*\n", isdigit_l('0', LC_GLOBAL_LOCALE)); + } + catch (...) { + printf("EXCEPTION!\n"); + } +} + diff --git a/tests/core/test_exceptions_alias.out b/tests/core/test_exceptions_alias.out new file mode 100644 index 00000000..2f67e501 --- /dev/null +++ b/tests/core/test_exceptions_alias.out @@ -0,0 +1,2 @@ +*1* +*1* diff --git a/tests/core/test_inlinejs3.in b/tests/core/test_inlinejs3.in index e21ed041..9ddd5907 100644 --- a/tests/core/test_inlinejs3.in +++ b/tests/core/test_inlinejs3.in @@ -15,6 +15,9 @@ int main(int argc, char **argv) { }, i, double(i) / 12); } + EM_ASM_INT({ globalVar = $0 }, sum); // no outputs, just input + sum = 0; + sum = EM_ASM_INT_V({ return globalVar }); // no inputs, just output printf("sum: %d\n", sum); return 0; } diff --git a/tests/core/test_longjmp_throw.cpp b/tests/core/test_longjmp_throw.cpp new file mode 100644 index 00000000..a5b658e8 --- /dev/null +++ b/tests/core/test_longjmp_throw.cpp @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <setjmp.h> + +static jmp_buf buf; +volatile int x = 0; + +void second(void) { + printf("second\n"); + if (x == 17) throw 5; + else longjmp(buf, -1); +} + +void first(void) { + printf("first\n"); + longjmp(buf, 1); +} + +int main() { + int jmpval = setjmp(buf); + if (!jmpval) { + x++; + first(); + printf("skipped\n"); + } else if (jmpval == 1) { + printf("result: %d %d\n", x, jmpval); + x++; + try { + second(); + } catch(int a) { + x--; + second(); + } + } else if (jmpval == -1) { + printf("result: %d %d\n", x, jmpval); + } + + return 0; +} diff --git a/tests/core/test_longjmp_throw.out b/tests/core/test_longjmp_throw.out new file mode 100644 index 00000000..e9cc7525 --- /dev/null +++ b/tests/core/test_longjmp_throw.out @@ -0,0 +1,4 @@ +first +result: 1 1 +second +result: 2 -1 diff --git a/tests/openal_playback.cpp b/tests/openal_playback.cpp index 13d619e6..6a8dae38 100644 --- a/tests/openal_playback.cpp +++ b/tests/openal_playback.cpp @@ -3,11 +3,15 @@ #include <AL/al.h> #include <AL/alc.h> #include <assert.h> +#include <stdint.h> +#include <unistd.h> +#ifdef EMSCRIPTEN #include <emscripten.h> +#endif void playSource(void* arg) { - ALuint source = reinterpret_cast<ALuint>(arg); + ALuint source = static_cast<ALuint>(reinterpret_cast<intptr_t>(arg)); ALint state; alGetSourcei(source, AL_SOURCE_STATE, &state); assert(state == AL_PLAYING); @@ -21,15 +25,32 @@ void playSource(void* arg) alGetSourcei(source, AL_SOURCE_STATE, &state); assert(state == AL_STOPPED); +#ifdef EMSCRIPTEN int result = 1; REPORT_RESULT(); +#endif } int main() { + int major, minor; + alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &major); + alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &minor); + + assert(major == 1); + + printf("ALC version: %i.%i\n", major, minor); + printf("Default device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER)); + ALCdevice* device = alcOpenDevice(NULL); ALCcontext* context = alcCreateContext(device, NULL); alcMakeContextCurrent(context); + assert(alGetString(AL_VERSION)); + + printf("OpenAL version: %s\n", alGetString(AL_VERSION)); + printf("OpenAL vendor: %s\n", alGetString(AL_VENDOR)); + printf("OpenAL renderer: %s\n", alGetString(AL_RENDERER)); + ALfloat listenerPos[] = {0.0, 0.0, 0.0}; ALfloat listenerVel[] = {0.0, 0.0, 0.0}; ALfloat listenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}; @@ -42,7 +63,11 @@ int main() { alGenBuffers(1, buffers); +#ifdef EMSCRIPTEN FILE* source = fopen("audio.wav", "rb"); +#else + FILE* source = fopen("sounds/audio.wav", "rb"); +#endif fseek(source, 0, SEEK_END); int size = ftell(source); fseek(source, 0, SEEK_SET); @@ -95,9 +120,21 @@ int main() { alBufferData(buffers[0], format, &buffer[offset], size - offset, frequency); + ALint val; + alGetBufferi(buffers[0], AL_FREQUENCY, &val); + assert(val == frequency); + alGetBufferi(buffers[0], AL_SIZE, &val); + assert(val == size - offset); + alGetBufferi(buffers[0], AL_BITS, &val); + assert(val == bits); + alGetBufferi(buffers[0], AL_CHANNELS, &val); + assert(val == channels); + ALuint sources[1]; alGenSources(1, sources); + assert(alIsSource(sources[0])); + alSourcei(sources[0], AL_BUFFER, buffers[0]); ALint state; @@ -109,7 +146,12 @@ int main() { alGetSourcei(sources[0], AL_SOURCE_STATE, &state); assert(state == AL_PLAYING); +#ifdef EMSCRIPTEN emscripten_async_call(playSource, reinterpret_cast<void*>(sources[0]), 700); +#else + usleep(700000); + playSource(reinterpret_cast<void*>(sources[0])); +#endif return 0; } diff --git a/tests/poppler/utils/pdftoppm.cc b/tests/poppler/utils/pdftoppm.cc index f600e5ba..4df0f5d8 100644 --- a/tests/poppler/utils/pdftoppm.cc +++ b/tests/poppler/utils/pdftoppm.cc @@ -183,6 +183,10 @@ static void savePageSlice(PDFDoc *doc, bitmap->writePNMFile(ppmFile); } } else { +#if EMSCRIPTEN // XXX EMSCRIPTEN: avoid writing to stdout, better for benchmarking + printf("avoiding writing to stdout\n"); +#else + #ifdef _WIN32 setmode(fileno(stdout), O_BINARY); #endif @@ -194,6 +198,7 @@ static void savePageSlice(PDFDoc *doc, } else { bitmap->writePNMFile(stdout); } +#endif } } diff --git a/tests/test_core.py b/tests/test_core.py index 97cba68f..18d7d74a 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1157,6 +1157,16 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) + def test_longjmp_throw(self): + if self.run_name == 'asm3': return self.skip('issue 2069') # FIXME + + for disable_throw in [0, 1]: + print disable_throw + Settings.DISABLE_EXCEPTION_CATCHING = disable_throw + test_path = path_from_root('tests', 'core', 'test_longjmp_throw') + src, output = (test_path + s for s in ('.cpp', '.out')) + self.do_run_from_file(src, output) + def test_setjmp_many(self): if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp: make MAX_SETJMPS take effect') @@ -1266,12 +1276,16 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co def test_exceptions_2(self): if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly') - Settings.DISABLE_EXCEPTION_CATCHING = 0 + if self.run_name == 'asm2x86': return self.skip('TODO') - test_path = path_from_root('tests', 'core', 'test_exceptions_2') - src, output = (test_path + s for s in ('.in', '.out')) + Settings.DISABLE_EXCEPTION_CATCHING = 0 - self.do_run_from_file(src, output) + for safe in [0,1]: + print safe + Settings.SAFE_HEAP = safe + test_path = path_from_root('tests', 'core', 'test_exceptions_2') + src, output = (test_path + s for s in ('.in', '.out')) + self.do_run_from_file(src, output) def test_exceptions_white_list(self): if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') @@ -1352,6 +1366,12 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co self.do_run_from_file(src, output) + def test_exceptions_alias(self): + Settings.DISABLE_EXCEPTION_CATCHING = 0 + test_path = path_from_root('tests', 'core', 'test_exceptions_alias') + src, output = (test_path + s for s in ('.c', '.out')) + self.do_run_from_file(src, output) + def test_async_exit(self): open('main.c', 'w').write(r''' #include <stdio.h> @@ -2051,7 +2071,6 @@ def process(filename): def test_bigswitch(self): if self.run_name != 'default': return self.skip('TODO: issue #781') - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') src = open(path_from_root('tests', 'bigswitch.cpp')).read() self.do_run(src, '''34962: GL_ARRAY_BUFFER (0x8892) @@ -5082,7 +5101,7 @@ def process(filename): 'structparam', 'uadd_overflow_ta2', 'extendedprecision', 'issue_39', 'emptystruct', 'phinonexist', 'quotedlabel', 'oob_ta2', 'phientryimplicit', 'phiself', 'invokebitcast', # invalid ir 'structphiparam', 'callwithstructural_ta2', 'callwithstructural64_ta2', 'structinparam', # pnacl limitations in ExpandStructRegs '2xi40', # pnacl limitations in ExpandGetElementPtr - 'legalizer_ta2', '514_ta2', # pnacl limitation in not legalizing i104, i96, etc. + 'legalizer_ta2', # pnacl limitation in not legalizing i104, i96, etc. 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME 'sillyfuncast2', 'sillybitcast', 'atomicrmw_unaligned' # TODO XXX ]: continue diff --git a/tests/test_other.py b/tests/test_other.py index 8895a911..bc05826e 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2324,3 +2324,30 @@ var Module = { print: function(x) { throw '<{(' + x + ')}>' } }; output = run_js(os.path.join(self.get_dir(), 'a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS) assert r'<{(123456789)}>' in output, output + def test_precompiled_headers(self): + self.clear() + + open('header.h', 'w').write('#define X 5\n') + Popen([PYTHON, EMCC, '-xc++-header', 'header.h', '-c']).communicate() + assert os.path.exists('header.h.gch') + + open('src.cpp', 'w').write(r''' +#include <stdio.h> +int main() { + printf("|%d|\n", X); + return 0; +} +''') + Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h']).communicate() + + output = run_js(self.in_dir('a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS) + assert '|5|' in output, output + + # also verify that the gch is actually used + err = Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h', '-Xclang', '-print-stats'], stderr=PIPE).communicate() + assert '*** PCH/Modules Loaded:\nModule: header.h.gch' in err[1], err[1] + # and sanity check it is not mentioned when not + try_delete('header.h.gch') + err = Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h', '-Xclang', '-print-stats'], stderr=PIPE).communicate() + assert '*** PCH/Modules Loaded:\nModule: header.h.gch' not in err[1], err[1] + |