Skip to content

Commit

Permalink
Merge pull request #75 from turbolent/prevent-nan-canonicalization
Browse files Browse the repository at this point in the history
Prevent NaN canonicalization when reading const instructions
  • Loading branch information
turbolent authored Jul 25, 2023
2 parents 2e095eb + 53eacd1 commit 91cb067
Show file tree
Hide file tree
Showing 17 changed files with 1,338 additions and 89 deletions.
145 changes: 75 additions & 70 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,30 @@ jobs:
system:
- { target: gcc, cc: gcc, }
- { target: clang, cc: clang, }
- { target: i386, toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static }
- { target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static }
- { target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static }
- { target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static }
- { target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static }
- { target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static }
- { target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static }
# fails on conversions.0 f32.convert_i64_s tests
# - { target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static }
- { target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static }
- { target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static }

# Architectures with expected failures (mostly due to FP issues, e.g. NaN representation, conversion, arithemtic)
- { target: i386, toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static }
- { target: hppa, toolchain: gcc-hppa-linux-gnu, cc: hppa-linux-gnu-gcc, qemu: qemu-hppa-static }
- { target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static }
# fails on float_exprs.87 f32.arithmetic_nan_bitpattern tests
# - { target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static }
- { target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static }
# fails on float_exprs.87 f32.arithmetic_nan_bitpattern tests
# - { target: mips64el, toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc, qemu: qemu-mips64el-static }
- { target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static }
# fails on float_exprs.87 f32.canonical_nan_bitpattern tests
- { target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static }
- { target: mips64el, toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc, qemu: qemu-mips64el-static }
- { target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static }

# Disabled due to miscompilation or qemu issues (?)
# - { target: sh4, toolchain: gcc-sh4-linux-gnu, cc: sh4-linux-gnu-gcc, qemu: qemu-sh4-static }
# - { target: sparc64, toolchain: gcc-sparc64-linux-gnu, cc: sparc64-linux-gnu-gcc, qemu: qemu-sparc64-static }
- { target: hppa, toolchain: gcc-hppa-linux-gnu, cc: hppa-linux-gnu-gcc, qemu: qemu-hppa-static }
# fails on f32_bitwise.0 copysign tests

# Disabled due to too large `switch'-statement
# - { target: m68k, toolchain: gcc-m68k-linux-gnu, cc: m68k-linux-gnu-gcc, qemu: qemu-m68k-static }
- { target: sh4, toolchain: gcc-sh4-linux-gnu, cc: sh4-linux-gnu-gcc, qemu: qemu-sh4-static }

env:
CC: ${{ matrix.system.cc }}
Expand Down Expand Up @@ -81,10 +82,10 @@ jobs:
name: Run w2c2 tests
env:
LDFLAGS: -static
ARCH: ${{ matrix.system.target }}
working-directory: ./tests
shell: bash
run: |
make run-tests 2>&1 | tee results && ! grep -q "^FAIL: " results
run: make run-tests
- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
Expand Down Expand Up @@ -118,65 +119,69 @@ jobs:
name: Run tests
working-directory: ./tests
shell: bash
run: |
make run-tests 2>&1 | tee results && ! grep -q "^FAIL: " results
env:
ARCH: ${{ matrix.system.target }}
run: make run-tests
- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
run: make BUILD=${{ matrix.build }} FEATURES="unistd sysuio systime sysresource strndup fcntl timespec lstat"

windows-mingw:
runs-on: windows-latest
name: "Windows (mingw), ${{ matrix.system.target }} (build=${{ matrix.build }}, threads=${{ matrix.threads }})"

strategy:
fail-fast: false
matrix:
build: [release, debug]
threads: [true, false]
system:
- { target: mingw64, env: x86_64 }
- { target: mingw32, env: i686 }

defaults:
run:
shell: msys2 {0}

env:
CC: gcc

steps:
- uses: actions/checkout@v3
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.system.target }}
install: >-
make
gcc
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
w2c2:
- 'w2c2/**'
wasi:
- 'wasi/**'
- if: steps.changes.outputs.w2c2 == 'true'
name: Build w2c2
env:
LDFLAGS: -static
working-directory: ./w2c2
run: make BUILD=${{ matrix.build }} FEATURES="getopt ${{ matrix.threads && 'threads' || '' }}"
- if: steps.changes.outputs.w2c2 == 'true'
name: Run tests
working-directory: ./tests
shell: bash
run: |
make run-tests 2>&1 | tee results && ! grep -q "^FAIL: " results
- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
run: make BUILD=${{ matrix.build }}
# Disabled due to sqrt issues
#
# windows-mingw:
# runs-on: windows-latest
# name: "Windows (mingw), ${{ matrix.system.target }} (build=${{ matrix.build }}, threads=${{ matrix.threads }})"
#
# strategy:
# fail-fast: false
# matrix:
# build: [release, debug]
# threads: [true, false]
# system:
# - { target: mingw64, env: x86_64 }
# - { target: mingw32, env: i686 }
#
# defaults:
# run:
# shell: msys2 {0}
#
# env:
# CC: gcc
#
# steps:
# - uses: actions/checkout@v3
# - uses: msys2/setup-msys2@v2
# with:
# msystem: ${{ matrix.system.target }}
# install: >-
# make
# gcc
# - uses: dorny/paths-filter@v2
# id: changes
# with:
# filters: |
# w2c2:
# - 'w2c2/**'
# wasi:
# - 'wasi/**'
# - if: steps.changes.outputs.w2c2 == 'true'
# name: Build w2c2
# env:
# LDFLAGS: -static
# working-directory: ./w2c2
# run: make BUILD=${{ matrix.build }} FEATURES="getopt ${{ matrix.threads && 'threads' || '' }}"
# - if: steps.changes.outputs.w2c2 == 'true'
# name: Run tests
# working-directory: ./tests
# shell: bash
# env:
# ARCH: ${{ matrix.system.target }}
# run: make run-tests
# - if: steps.changes.outputs.wasi == 'true'
# name: Build wasi
# working-directory: ./wasi
# run: make BUILD=${{ matrix.build }}

windows-msvc:
runs-on: windows-2019
Expand All @@ -192,14 +197,14 @@ jobs:
- 'w2c2/**'
wasi:
- 'wasi/**'
- # if: steps.changes.outputs.w2c2 == 'true'
- if: steps.changes.outputs.w2c2 == 'true'
name: Build w2c2
working-directory: ./w2c2
run: |
cmake -Bbuild
cmake --build build
# TODO: run tests
- # if: steps.changes.outputs.wasi == 'true'
- if: steps.changes.outputs.wasi == 'true'
name: Build wasi
working-directory: ./wasi
run: |
Expand Down
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test_*
!test_*.out
6 changes: 3 additions & 3 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ run-tests-%:

run-test-%: test_%$(EXE)
echo ">>>" $<
$(EXECUTE) ./$<
$(PYTHON3) run.py $(if $(EXECUTE),-e $(EXECUTE),) $(if $(ARCH),-a $(ARCH),) $<
echo

test_%$(EXE): test_%.o main.o
$(CC) $< main.o -o $@ $(LDFLAGS)
$(CC) $(CFLAGS) $< main.o -o $@ $(LDFLAGS)

test_%.c: gen/%.wasm
echo "#include \"test.h\"" > $@
Expand All @@ -62,4 +62,4 @@ gen-%:
$(PYTHON3) gen.py $*

clean:
-rm -f main.o test_*
-rm -f main.o test_*.o
46 changes: 46 additions & 0 deletions tests/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import argparse
import subprocess
import os
import difflib
import sys

def main():
parser = argparse.ArgumentParser()
parser.add_argument('test')
parser.add_argument('-a', '--arch')
parser.add_argument('-e', '--execute')
args = parser.parse_args()

command = []

if args.execute:
command.append(args.execute)
command.append(os.path.abspath(args.test))

output = subprocess.run(command, check=True, stderr=subprocess.PIPE).stderr.decode('utf-8').strip()

print(output)

if args.arch:
path = args.test + '.' + args.arch + '.out'
if os.path.isfile(path):
expected = ''
with open(path, 'r') as f:
expected = f.read()
diff = list(difflib.unified_diff(
expected.splitlines(keepends=True),
output.splitlines(keepends=True),
fromfile='expected',
tofile='actual'
))
if diff:
print()
sys.stdout.writelines(diff)
exit(1)
return

if 'FAIL: ' in output:
exit(1)

if __name__ == "__main__":
main()
Loading

0 comments on commit 91cb067

Please sign in to comment.