Commit a67fc448 by Jim Stichnoth

Subzero: Run sandboxed cross tests, and do some cleanup.

Tests all cross tests in both sandboxed and unsandboxed modes. Unfortunately, crosstest run time is more than doubled because of LTO of the crosstest drivers. (We may want to add "full" and "lite" versions of cross tests.) LLVM triple strings are removed where possible (from .ll files), and when generated, we use just i686 or i686-nacl. "Fix" the integrated assembler to emit the lock prefix after the 16-bit operand prefix, to make the validator happy. Don't add external symbol references to the ELF file for llvm.* intrinsic functions. Make the ELF object writer honor the -externalize argument. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4092 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/973823003
parent 437ceff2
...@@ -10,103 +10,116 @@ set -eux ...@@ -10,103 +10,116 @@ set -eux
PATH="../pydir:${PATH}" PATH="../pydir:${PATH}"
OPTLEVELS="m1 2" OPTLEVELS="m1 2"
ATTRIBUTES="sse2 sse4.1" ATTRIBUTES="sse2 sse4.1"
SANDBOX="0 1"
OUTDIR=Output OUTDIR=Output
# Clean the output directory to avoid reusing stale results. # Clean the output directory to avoid reusing stale results.
rm -rf "${OUTDIR}" rm -rf "${OUTDIR}"
mkdir -p "${OUTDIR}" mkdir -p "${OUTDIR}"
for optlevel in ${OPTLEVELS} ; do for sb in ${SANDBOX} ; do
for optlevel in ${OPTLEVELS} ; do
for attribute in ${ATTRIBUTES} ; do for attribute in ${ATTRIBUTES} ; do
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=simple_loop.c \ --test=simple_loop.c \
--driver=simple_loop_main.c \ --driver=simple_loop_main.c \
--output=simple_loop_O${optlevel}_${attribute} --output=simple_loop_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=mem_intrin.cpp \ --test=mem_intrin.cpp \
--driver=mem_intrin_main.cpp \ --driver=mem_intrin_main.cpp \
--output=mem_intrin_O${optlevel}_${attribute} --output=mem_intrin_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_arith.cpp \ --test=test_arith.cpp \
--test=test_arith_frem.ll \ --test=test_arith_frem.ll \
--test=test_arith_sqrt.ll \ --test=test_arith_sqrt.ll \
--driver=test_arith_main.cpp \ --driver=test_arith_main.cpp \
--output=test_arith_O${optlevel}_${attribute} --output=test_arith_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_bitmanip.cpp --test=test_bitmanip_intrin.ll \ --test=test_bitmanip.cpp --test=test_bitmanip_intrin.ll \
--driver=test_bitmanip_main.cpp \ --driver=test_bitmanip_main.cpp \
--output=test_bitmanip_O${optlevel}_${attribute} --output=test_bitmanip_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ --target=x8632 \ --prefix=Subzero_ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_calling_conv.cpp \ --test=test_calling_conv.cpp \
--driver=test_calling_conv_main.cpp \ --driver=test_calling_conv_main.cpp \
--output=test_calling_conv_O${optlevel}_${attribute} --output=test_calling_conv_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_cast.cpp --test=test_cast_to_u1.ll \ --test=test_cast.cpp --test=test_cast_to_u1.ll \
--test=test_cast_vectors.ll \ --test=test_cast_vectors.ll \
--driver=test_cast_main.cpp \ --driver=test_cast_main.cpp \
--output=test_cast_O${optlevel}_${attribute} --output=test_cast_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_fcmp.pnacl.ll \ --test=test_fcmp.pnacl.ll \
--driver=test_fcmp_main.cpp \ --driver=test_fcmp_main.cpp \
--output=test_fcmp_O${optlevel}_${attribute} --output=test_fcmp_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_global.cpp \ --test=test_global.cpp \
--driver=test_global_main.cpp \ --driver=test_global_main.cpp \
--output=test_global_O${optlevel}_${attribute} --output=test_global_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_icmp.cpp --test=test_icmp_i1vec.ll \ --test=test_icmp.cpp --test=test_icmp_i1vec.ll \
--driver=test_icmp_main.cpp \ --driver=test_icmp_main.cpp \
--output=test_icmp_O${optlevel}_${attribute} --output=test_icmp_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_select.ll \ --test=test_select.ll \
--driver=test_select_main.cpp \ --driver=test_select_main.cpp \
--output=test_select_O${optlevel}_${attribute} --output=test_select_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_stacksave.c \ --test=test_stacksave.c \
--driver=test_stacksave_main.c \ --driver=test_stacksave_main.c \
--output=test_stacksave_O${optlevel}_${attribute} --output=test_stacksave_sb${sb}_O${optlevel}_${attribute}
# Compile the non-subzero object files straight from source # Compile the non-subzero object files straight from source
# since the native LLVM backend does not understand how to # since the native LLVM backend does not understand how to
...@@ -114,36 +127,47 @@ for optlevel in ${OPTLEVELS} ; do ...@@ -114,36 +127,47 @@ for optlevel in ${OPTLEVELS} ; do
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ \ --prefix=Subzero_ \
--target=x8632 \ --target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_sync_atomic.cpp \ --test=test_sync_atomic.cpp \
--crosstest-bitcode=0 \ --crosstest-bitcode=0 \
--driver=test_sync_atomic_main.cpp \ --driver=test_sync_atomic_main.cpp \
--output=test_sync_atomic_O${optlevel}_${attribute} --output=test_sync_atomic_sb${sb}_O${optlevel}_${attribute}
crosstest.py -O${optlevel} --mattr ${attribute} \ crosstest.py -O${optlevel} --mattr ${attribute} \
--prefix=Subzero_ --target=x8632 \ --prefix=Subzero_ \
--target=x8632 \
--sandbox=${sb} \
--dir="${OUTDIR}" \ --dir="${OUTDIR}" \
--test=test_vector_ops.ll \ --test=test_vector_ops.ll \
--driver=test_vector_ops_main.cpp \ --driver=test_vector_ops_main.cpp \
--output=test_vector_ops_O${optlevel}_${attribute} --output=test_vector_ops_sb${sb}_O${optlevel}_${attribute}
done done
done
done done
for optlevel in ${OPTLEVELS} ; do for sb in ${SANDBOX} ; do
if [ $sb = 0 ] ; then
PREFIX=
else
PREFIX="../../../../run.py -q"
fi
for optlevel in ${OPTLEVELS} ; do
for attribute in ${ATTRIBUTES}; do for attribute in ${ATTRIBUTES}; do
"${OUTDIR}"/simple_loop_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/simple_loop_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/mem_intrin_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/mem_intrin_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_arith_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_arith_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_bitmanip_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_bitmanip_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_calling_conv_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_calling_conv_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_cast_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_cast_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_fcmp_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_fcmp_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_global_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_global_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_icmp_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_icmp_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_select_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_select_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_stacksave_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_stacksave_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_sync_atomic_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_sync_atomic_sb${sb}_O${optlevel}_${attribute}
"${OUTDIR}"/test_vector_ops_O${optlevel}_${attribute} ${PREFIX} "${OUTDIR}"/test_vector_ops_sb${sb}_O${optlevel}_${attribute}
done
done done
done done
target triple = "i686-pc-linux-gnu"
define float @_Z6myFremff(float %a, float %b) { define float @_Z6myFremff(float %a, float %b) {
%rem = frem float %a, %b %rem = frem float %a, %b
ret float %rem ret float %rem
......
target triple = "i686-pc-linux-gnu"
declare float @llvm.sqrt.f32(float) declare float @llvm.sqrt.f32(float)
declare double @llvm.sqrt.f64(double) declare double @llvm.sqrt.f64(double)
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
; Also, normalize the intrinsic to take a single parameter when there ; Also, normalize the intrinsic to take a single parameter when there
; can be two, as is the case for ctlz and cttz. ; can be two, as is the case for ctlz and cttz.
target triple = "i686-pc-linux-gnu"
declare i32 @llvm.ctlz.i32(i32, i1) declare i32 @llvm.ctlz.i32(i32, i1)
declare i64 @llvm.ctlz.i64(i64, i1) declare i64 @llvm.ctlz.i64(i64, i1)
......
target triple = "i686-pc-linux-gnu"
define i32 @_Z4castIxbET0_T_(i64 %a) { define i32 @_Z4castIxbET0_T_(i64 %a) {
entry: entry:
; %tobool = icmp ne i64 %a, 0 ; %tobool = icmp ne i64 %a, 0
......
target triple = "i686-pc-linux-gnu"
define <4 x float> @_Z4castIDv4_iDv4_fET0_T_(<4 x i32> %a) { define <4 x float> @_Z4castIDv4_iDv4_fET0_T_(<4 x i32> %a) {
entry: entry:
%0 = sitofp <4 x i32> %a to <4 x float> %0 = sitofp <4 x i32> %a to <4 x float>
......
target triple = "i686-pc-linux-gnu"
; This file is extracted from fp.pnacl.ll and vector-fcmp.ll in the lit ; This file is extracted from fp.pnacl.ll and vector-fcmp.ll in the lit
; tests, with the "internal" attribute removed from the functions. ; tests, with the "internal" attribute removed from the functions.
......
target triple = "i686-pc-linux-gnu"
define <16 x i8> @_Z8icmpi1EqDv16_aS_(<16 x i8> %a, <16 x i8> %b) { define <16 x i8> @_Z8icmpi1EqDv16_aS_(<16 x i8> %a, <16 x i8> %b) {
entry: entry:
%a.trunc = trunc <16 x i8> %a to <16 x i1> %a.trunc = trunc <16 x i8> %a to <16 x i1>
......
target triple = "i686-pc-linux-gnu"
define <4 x float> @_Z6selectDv4_iDv4_fS0_(<4 x i32> %cond.ext, <4 x float> %arg1, <4 x float> %arg2) { define <4 x float> @_Z6selectDv4_iDv4_fS0_(<4 x i32> %cond.ext, <4 x float> %arg1, <4 x float> %arg2) {
entry: entry:
%cond = trunc <4 x i32> %cond.ext to <4 x i1> %cond = trunc <4 x i32> %cond.ext to <4 x i1>
......
target triple = "i686-pc-linux-gnu"
define <4 x float> @insertelement_v4f32(<4 x float> %vec, float %elt, i32 %idx) { define <4 x float> @insertelement_v4f32(<4 x float> %vec, float %elt, i32 %idx) {
switch i32 %idx, label %abort [ switch i32 %idx, label %abort [
i32 0, label %idx0 i32 0, label %idx0
......
...@@ -74,12 +74,12 @@ def main(): ...@@ -74,12 +74,12 @@ def main():
'{srcdir}/szrt_ll.ll'.format(srcdir=srcdir)] '{srcdir}/szrt_ll.ll'.format(srcdir=srcdir)]
# Translate tempdir/szrt.ll and srcdir/szrt_ll.ll to szrt_native_x8632.o # Translate tempdir/szrt.ll and srcdir/szrt_ll.ll to szrt_native_x8632.o
Translate(ll_files, Translate(ll_files,
['-mtriple=i386-unknown-linux-gnu', '-mcpu=pentium4m'], ['-mtriple=i686', '-mcpu=pentium4m'],
'{rtdir}/szrt_native_x8632.o'.format(rtdir=rtdir), '{rtdir}/szrt_native_x8632.o'.format(rtdir=rtdir),
args.verbose) args.verbose)
# Translate tempdir/szrt.ll and srcdir/szrt_ll.ll to szrt_sb_x8632.o # Translate tempdir/szrt.ll and srcdir/szrt_ll.ll to szrt_sb_x8632.o
Translate(ll_files, Translate(ll_files,
['-mtriple=i686-none-nacl-gnu', '-mcpu=pentium4m'], ['-mtriple=i686-nacl', '-mcpu=pentium4m'],
'{rtdir}/szrt_sb_x8632.o'.format(rtdir=rtdir), '{rtdir}/szrt_sb_x8632.o'.format(rtdir=rtdir),
args.verbose) args.verbose)
finally: finally:
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
import argparse import argparse
import os import os
import re
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
...@@ -10,7 +9,7 @@ import tempfile ...@@ -10,7 +9,7 @@ import tempfile
from utils import shellcmd from utils import shellcmd
from utils import FindBaseNaCl from utils import FindBaseNaCl
if __name__ == '__main__': def main():
"""Builds a cross-test binary that allows functions translated by """Builds a cross-test binary that allows functions translated by
Subzero and llc to be compared. Subzero and llc to be compared.
...@@ -49,6 +48,9 @@ if __name__ == '__main__': ...@@ -49,6 +48,9 @@ if __name__ == '__main__':
dest='attr', choices=['sse2', 'sse4.1'], dest='attr', choices=['sse2', 'sse4.1'],
metavar='ATTRIBUTE', metavar='ATTRIBUTE',
help='Target attribute. Default %(default)s.') help='Target attribute. Default %(default)s.')
argparser.add_argument('--sandbox', required=False, default=0, type=int,
dest='sandbox',
help='Use sandboxing. Default "%(default)s".')
argparser.add_argument('--prefix', required=True, argparser.add_argument('--prefix', required=True,
metavar='SZ_PREFIX', metavar='SZ_PREFIX',
help='String prepended to Subzero symbol names') help='String prepended to Subzero symbol names')
...@@ -71,14 +73,11 @@ if __name__ == '__main__': ...@@ -71,14 +73,11 @@ if __name__ == '__main__':
args = argparser.parse_args() args = argparser.parse_args()
nacl_root = FindBaseNaCl() nacl_root = FindBaseNaCl()
# Prepend PNaCl bin to $PATH. bindir = ('{root}/toolchain/linux_x86/pnacl_newlib/bin'
os.environ['PATH'] = nacl_root + \ .format(root=nacl_root))
'/toolchain/linux_x86/pnacl_newlib/bin' + \ triple = arch_map[args.target] + ('-nacl' if args.sandbox else '')
os.pathsep + os.environ['PATH']
objs = [] objs = []
remove_internal = re.compile('^define internal ')
fix_target = re.compile('le32-unknown-nacl')
for arg in args.test: for arg in args.test:
base, ext = os.path.splitext(arg) base, ext = os.path.splitext(arg)
if ext == '.ll': if ext == '.ll':
...@@ -87,68 +86,61 @@ if __name__ == '__main__': ...@@ -87,68 +86,61 @@ if __name__ == '__main__':
bitcode = os.path.join(args.dir, base + '.pnacl.ll') bitcode = os.path.join(args.dir, base + '.pnacl.ll')
shellcmd(['../pydir/build-pnacl-ir.py', '--disable-verify', shellcmd(['../pydir/build-pnacl-ir.py', '--disable-verify',
'--dir', args.dir, arg]) '--dir', args.dir, arg])
# Read in the bitcode file, fix it up, and rewrite the file.
f = open(bitcode)
ll_lines = f.readlines()
f.close()
f = open(bitcode, 'w')
for line in ll_lines:
line = remove_internal.sub('define ', line)
line = fix_target.sub('i686-pc-linux-gnu', line)
f.write(line)
f.close()
base_sz = '%s.O%s.%s.%s' % (base, args.optlevel, args.attr, args.target) base_sz = '{base}.{sb}.O{opt}.{attr}.{target}'.format(
base=base, sb='sb' if args.sandbox else 'nat', opt=args.optlevel,
attr=args.attr, target=args.target)
asm_sz = os.path.join(args.dir, base_sz + '.sz.s') asm_sz = os.path.join(args.dir, base_sz + '.sz.s')
obj_sz = os.path.join(args.dir, base_sz + '.sz.o') obj_sz = os.path.join(args.dir, base_sz + '.sz.o')
obj_llc = os.path.join(args.dir, base + '.llc.o') obj_llc = os.path.join(args.dir, base_sz + '.llc.o')
shellcmd(['../pnacl-sz', shellcmd(['../pnacl-sz',
'-O' + args.optlevel, '-O' + args.optlevel,
'-mattr=' + args.attr, '-mattr=' + args.attr,
'--target=' + args.target, '--target=' + args.target,
'--sandbox=' + str(args.sandbox),
'--prefix=' + args.prefix, '--prefix=' + args.prefix,
'-allow-uninitialized-globals', '-allow-uninitialized-globals',
'-externalize',
'-filetype=' + args.filetype, '-filetype=' + args.filetype,
'-o=' + (obj_sz if args.filetype == 'obj' else asm_sz), '-o=' + (obj_sz if args.filetype == 'obj' else asm_sz),
bitcode]) bitcode])
if args.filetype != 'obj': if args.filetype != 'obj':
shellcmd(['llvm-mc', shellcmd(['{bin}/llvm-mc'.format(bin=bindir),
'-triple=' + arch_map[args.target], '-triple=' + triple,
'-filetype=obj', '-filetype=obj',
'-o=' + obj_sz, '-o=' + obj_sz,
asm_sz]) asm_sz])
objs.append(obj_sz) objs.append(obj_sz)
# Each original bitcode file needs to be translated by the if args.crosstest_bitcode:
# LLVM toolchain and have its object file linked in. There shellcmd(['{bin}/pnacl-llc'.format(bin=bindir),
# are two ways to do this: explicitly use llc, or include the '-mtriple=' + triple,
# .ll file in the link command. It turns out that these two # Use sse2 instructions regardless of input -mattr
# approaches can produce different semantics on some undefined # argument to avoid differences in (undefined) behavior of
# bitcode behavior. Specifically, LLVM produces different # converting NaN to int.
# results for overflowing fptoui instructions for i32 and i64 '-mattr=sse2',
# on x86-32. As it turns out, Subzero lowering was based on '-externalize',
# inspecting the object code produced by the direct llc
# command, so we need to directly run llc on the bitcode, even
# though it makes this script longer, to avoid spurious
# failures. This behavior can be inspected by switching
# use_llc between True and False.
use_llc = False
pure_c = os.path.splitext(args.driver)[1] == '.c'
if not args.crosstest_bitcode:
objs.append(arg)
elif use_llc:
shellcmd(['llc'
'-filetype=obj', '-filetype=obj',
'-o=' + obj_llc, '-o=' + obj_llc,
bitcode]) bitcode])
objs.append(obj_llc) objs.append(obj_llc)
else: else:
objs.append(bitcode) objs.append(arg)
# Add szrt_sb_x8632.o or szrt_native_x8632.o.
objs.append(( objs.append((
'{root}/toolchain_build/src/subzero/build/runtime/' + '{root}/toolchain_build/src/subzero/build/runtime/' +
'szrt_native_x8632.o' 'szrt_{sb}_' + args.target + '.o'
).format(root=nacl_root)) ).format(root=nacl_root, sb='sb' if args.sandbox else 'native'))
linker = 'clang' if pure_c else 'clang++' pure_c = os.path.splitext(args.driver)[1] == '.c'
shellcmd([linker, '-g', '-m32', args.driver] + # Set compiler to clang, clang++, pnacl-clang, or pnacl-clang++.
objs + compiler = '{bin}/{prefix}{cc}'.format(
['-lm', '-lpthread', '-o', os.path.join(args.dir, args.output)]) bin=bindir, prefix='pnacl-' if args.sandbox else '',
cc='clang' if pure_c else 'clang++')
sb_native_args = (['-O0', '--pnacl-allow-native', '-arch', 'x8632']
if args.sandbox else
['-g', '-m32', '-lm', '-lpthread'])
shellcmd([compiler, args.driver] + objs +
['-o', os.path.join(args.dir, args.output)] + sb_native_args)
if __name__ == '__main__':
main()
...@@ -112,7 +112,10 @@ def main(): ...@@ -112,7 +112,10 @@ def main():
asm_temp.close() asm_temp.close()
if args.assemble and args.filetype != 'obj': if args.assemble and args.filetype != 'obj':
cmd += ['|', os.path.join(llvm_bin_path, 'llvm-mc'), cmd += ['|', os.path.join(llvm_bin_path, 'llvm-mc'),
'-triple=i686-none-nacl', # TODO(stichnot): -triple=i686-nacl should be used for a
# sandboxing test. This means there should be an args.sandbox
# argument that also gets passed through to pnacl-sz.
'-triple=i686',
'-filetype=obj', '-o', asm_temp.name] '-filetype=obj', '-o', asm_temp.name]
elif asm_temp: elif asm_temp:
cmd += ['-o', asm_temp.name] cmd += ['-o', asm_temp.name]
......
...@@ -16,27 +16,9 @@ ...@@ -16,27 +16,9 @@
#include <stdint.h> #include <stdint.h>
// TODO(stichnot): The various NaN cross tests try to map Subzero's uint32_t __Sz_fptoui_f32_i32(float value) { return (uint32_t)value; }
// undefined behavior to the same as llc's undefined behavior, as
// observed by the cross tests. This will have to be kept up to date
// with any future changes to llc, and may also have to be different
// for different targets. It would be better to find a more
// appropriate set of llc options when building the Subzero runtime.
//
// We test for NaN using "Value==Value" instead of using isnan(Value)
// to avoid an external dependency on fpclassify().
uint32_t __Sz_fptoui_f32_i32(float Value) {
if (Value == Value) // NaNaN
return (uint32_t)Value;
return 0x80000000;
}
uint32_t __Sz_fptoui_f64_i32(double Value) { uint32_t __Sz_fptoui_f64_i32(double value) { return (uint32_t)value; }
if (Value == Value) // NaNaN
return (uint32_t)Value;
return 0x80000000;
}
uint64_t __Sz_fptoui_f32_i64(float Value) { return (uint64_t)Value; } uint64_t __Sz_fptoui_f32_i64(float Value) { return (uint64_t)Value; }
......
...@@ -555,20 +555,16 @@ private: ...@@ -555,20 +555,16 @@ private:
if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) { if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) {
// Check if this direct call is to an Intrinsic (starts with "llvm.") // Check if this direct call is to an Intrinsic (starts with "llvm.")
static const char LLVMPrefix[] = "llvm."; bool BadIntrinsic;
const size_t LLVMPrefixLen = strlen(LLVMPrefix); Info = Ctx->getIntrinsicsInfo().find(Target->getName(), BadIntrinsic);
Ice::IceString Name = Target->getName(); if (BadIntrinsic) {
if (Name.substr(0, LLVMPrefixLen) == LLVMPrefix) {
Ice::IceString NameSuffix = Name.substr(LLVMPrefixLen);
Info = Ctx->getIntrinsicsInfo().find(NameSuffix);
if (!Info) {
report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") + report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") +
LLVMObjectAsString(Inst)); LLVMObjectAsString(Inst));
} }
if (Info)
NewInst = Ice::InstIntrinsicCall::create(Func.get(), NumArgs, Dest, NewInst = Ice::InstIntrinsicCall::create(Func.get(), NumArgs, Dest,
CallTarget, Info->Info); CallTarget, Info->Info);
} }
}
// Not an intrinsic call. // Not an intrinsic call.
if (NewInst == nullptr) { if (NewInst == nullptr) {
......
...@@ -244,7 +244,7 @@ void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, ...@@ -244,7 +244,7 @@ void ELFObjectWriter::writeFunctionCode(const IceString &FuncName,
Section->appendData(Str, Asm->getBufferView()); Section->appendData(Str, Asm->getBufferView());
uint8_t SymbolType; uint8_t SymbolType;
uint8_t SymbolBinding; uint8_t SymbolBinding;
if (IsInternal) { if (IsInternal && !Ctx.getFlags().getDisableInternal()) {
SymbolType = STT_NOTYPE; SymbolType = STT_NOTYPE;
SymbolBinding = STB_LOCAL; SymbolBinding = STB_LOCAL;
} else { } else {
...@@ -545,6 +545,12 @@ void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { ...@@ -545,6 +545,12 @@ void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) {
for (const Constant *S : UndefSyms) { for (const Constant *S : UndefSyms) {
const auto Sym = llvm::cast<ConstantRelocatable>(S); const auto Sym = llvm::cast<ConstantRelocatable>(S);
const IceString &Name = Sym->getName(); const IceString &Name = Sym->getName();
bool BadIntrinsic;
const Intrinsics::FullIntrinsicInfo *Info =
Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic);
if (Info)
continue;
assert(!BadIntrinsic);
assert(Sym->getOffset() == 0); assert(Sym->getOffset() == 0);
assert(Sym->getSuppressMangling()); assert(Sym->getSuppressMangling());
SymTab->noteUndefinedSym(Name, NullSection); SymTab->noteUndefinedSym(Name, NullSection);
......
...@@ -1640,11 +1640,7 @@ void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { ...@@ -1640,11 +1640,7 @@ void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
assert(VarReg->hasReg()); assert(VarReg->hasReg());
const RegX8632::GPRRegister Reg = const RegX8632::GPRRegister Reg =
RegX8632::getEncodedGPR(VarReg->getRegNum()); RegX8632::getEncodedGPR(VarReg->getRegNum());
if (Locked) { Asm->cmpxchg(Ty, Addr, Reg, Locked);
Asm->LockCmpxchg(Ty, Addr, Reg);
} else {
Asm->cmpxchg(Ty, Addr, Reg);
}
} }
void InstX8632Cmpxchg::dump(const Cfg *Func) const { void InstX8632Cmpxchg::dump(const Cfg *Func) const {
...@@ -1676,10 +1672,7 @@ void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { ...@@ -1676,10 +1672,7 @@ void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
const x86::Address Addr = Mem->toAsmAddress(Asm); const x86::Address Addr = Mem->toAsmAddress(Asm);
if (Locked) { Asm->cmpxchg8b(Addr, Locked);
Asm->lock();
}
Asm->cmpxchg8b(Addr);
} }
void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
...@@ -2731,10 +2724,7 @@ void InstX8632Xadd::emitIAS(const Cfg *Func) const { ...@@ -2731,10 +2724,7 @@ void InstX8632Xadd::emitIAS(const Cfg *Func) const {
assert(VarReg->hasReg()); assert(VarReg->hasReg());
const RegX8632::GPRRegister Reg = const RegX8632::GPRRegister Reg =
RegX8632::getEncodedGPR(VarReg->getRegNum()); RegX8632::getEncodedGPR(VarReg->getRegNum());
if (Locked) { Asm->xadd(Ty, Addr, Reg, Locked);
Asm->lock();
}
Asm->xadd(Ty, Addr, Reg);
} }
void InstX8632Xadd::dump(const Cfg *Func) const { void InstX8632Xadd::dump(const Cfg *Func) const {
......
...@@ -220,11 +220,19 @@ Intrinsics::Intrinsics() { ...@@ -220,11 +220,19 @@ Intrinsics::Intrinsics() {
Intrinsics::~Intrinsics() {} Intrinsics::~Intrinsics() {}
const Intrinsics::FullIntrinsicInfo * const Intrinsics::FullIntrinsicInfo *Intrinsics::find(const IceString &Name,
Intrinsics::find(const IceString &Name) const { bool &Error) const {
auto it = Map.find(Name); static const char LLVMPrefix[] = "llvm.";
if (it == Map.end()) const size_t LLVMPrefixLen = strlen(LLVMPrefix);
Error = false;
if (Name.substr(0, LLVMPrefixLen) != LLVMPrefix)
return nullptr; return nullptr;
IceString NameSuffix = Name.substr(LLVMPrefixLen);
auto it = Map.find(NameSuffix);
if (it == Map.end()) {
Error = true;
return nullptr;
}
return &it->second; return &it->second;
} }
......
...@@ -145,11 +145,14 @@ public: ...@@ -145,11 +145,14 @@ public:
Type getArgType(SizeT Index) const; Type getArgType(SizeT Index) const;
}; };
// Find the information about a given intrinsic, based on function name. // Find the information about a given intrinsic, based on function name. If
// The function name is expected to have the common "llvm." prefix // the function name does not have the common "llvm." prefix, nullptr is
// stripped. If found, returns a reference to a FullIntrinsicInfo entry // returned and Error is set to false. Otherwise, tries to find a reference
// (valid for the lifetime of the map). Otherwise returns null. // to a FullIntrinsicInfo entry (valid for the lifetime of the map). If
const FullIntrinsicInfo *find(const IceString &Name) const; // found, sets Error to false and returns the reference. If not found, sets
// Error to true and returns nullptr (indicating an unknown "llvm.foo"
// intrinsic).
const FullIntrinsicInfo *find(const IceString &Name, bool &Error) const;
private: private:
// TODO(jvoung): May want to switch to something like LLVM's StringMap. // TODO(jvoung): May want to switch to something like LLVM's StringMap.
......
...@@ -1573,18 +1573,6 @@ private: ...@@ -1573,18 +1573,6 @@ private:
return VectorIndexValid; return VectorIndexValid;
} }
// Returns true if the Str begins with Prefix.
bool isStringPrefix(const Ice::IceString &Str, const Ice::IceString &Prefix) {
const size_t PrefixSize = Prefix.size();
if (Str.size() < PrefixSize)
return false;
for (size_t i = 0; i < PrefixSize; ++i) {
if (Str[i] != Prefix[i])
return false;
}
return true;
}
// Takes the PNaCl bitcode binary operator Opcode, and the opcode // Takes the PNaCl bitcode binary operator Opcode, and the opcode
// type Ty, and sets Op to the corresponding ICE binary // type Ty, and sets Op to the corresponding ICE binary
// opcode. Returns true if able to convert, false otherwise. // opcode. Returns true if able to convert, false otherwise.
...@@ -2511,13 +2499,11 @@ void FunctionParser::ProcessRecord() { ...@@ -2511,13 +2499,11 @@ void FunctionParser::ProcessRecord() {
ReturnType = Signature.getReturnType(); ReturnType = Signature.getReturnType();
// Check if this direct call is to an Intrinsic (starts with "llvm.") // Check if this direct call is to an Intrinsic (starts with "llvm.")
static Ice::IceString LLVMPrefix("llvm."); bool BadIntrinsic;
const Ice::IceString &Name = Fcn->getName(); const Ice::IceString &Name = Fcn->getName();
if (isStringPrefix(Name, LLVMPrefix)) { IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find(
Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); Name, BadIntrinsic);
IntrinsicInfo = if (BadIntrinsic) {
getTranslator().getContext()->getIntrinsicsInfo().find(Suffix);
if (!IntrinsicInfo) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Invalid PNaCl intrinsic call to " << Name; StrBuf << "Invalid PNaCl intrinsic call to " << Name;
...@@ -2525,7 +2511,6 @@ void FunctionParser::ProcessRecord() { ...@@ -2525,7 +2511,6 @@ void FunctionParser::ProcessRecord() {
appendErrorInstruction(ReturnType); appendErrorInstruction(ReturnType);
return; return;
} }
}
} else { } else {
if (getFlags().getStubConstantCalls() && if (getFlags().getStubConstantCalls() &&
llvm::isa<Ice::ConstantInteger32>(Callee)) { llvm::isa<Ice::ConstantInteger32>(Callee)) {
......
...@@ -2312,10 +2312,13 @@ void AssemblerX86::lock() { ...@@ -2312,10 +2312,13 @@ void AssemblerX86::lock() {
EmitUint8(0xF0); EmitUint8(0xF0);
} }
void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg) { void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg,
bool Locked) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
if (Locked)
EmitUint8(0xF0);
EmitUint8(0x0F); EmitUint8(0x0F);
if (isByteSizedArithType(Ty)) if (isByteSizedArithType(Ty))
EmitUint8(0xB0); EmitUint8(0xB0);
...@@ -2324,17 +2327,22 @@ void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg) { ...@@ -2324,17 +2327,22 @@ void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg) {
EmitOperand(reg, address); EmitOperand(reg, address);
} }
void AssemblerX86::cmpxchg8b(const Address &address) { void AssemblerX86::cmpxchg8b(const Address &address, bool Locked) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Locked)
EmitUint8(0xF0);
EmitUint8(0x0F); EmitUint8(0x0F);
EmitUint8(0xC7); EmitUint8(0xC7);
EmitOperand(1, address); EmitOperand(1, address);
} }
void AssemblerX86::xadd(Type Ty, const Address &addr, GPRRegister reg) { void AssemblerX86::xadd(Type Ty, const Address &addr, GPRRegister reg,
bool Locked) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
if (Locked)
EmitUint8(0xF0);
EmitUint8(0x0F); EmitUint8(0x0F);
if (isByteSizedArithType(Ty)) if (isByteSizedArithType(Ty))
EmitUint8(0xC0); EmitUint8(0xC0);
......
...@@ -803,16 +803,11 @@ public: ...@@ -803,16 +803,11 @@ public:
void mfence(); void mfence();
void lock(); void lock();
void cmpxchg(Type Ty, const Address &address, GPRRegister reg); void cmpxchg(Type Ty, const Address &address, GPRRegister reg, bool Locked);
void cmpxchg8b(const Address &address); void cmpxchg8b(const Address &address, bool Locked);
void xadd(Type Ty, const Address &address, GPRRegister reg); void xadd(Type Ty, const Address &address, GPRRegister reg, bool Locked);
void xchg(Type Ty, const Address &address, GPRRegister reg); void xchg(Type Ty, const Address &address, GPRRegister reg);
void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) {
lock();
cmpxchg(Ty, address, reg);
}
void EmitSegmentOverride(uint8_t prefix); void EmitSegmentOverride(uint8_t prefix);
intptr_t PreferredLoopAlignment() { return 16; } intptr_t PreferredLoopAlignment() { return 16; }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
; RUN: -relocations -symbols %t | FileCheck %s ; RUN: -relocations -symbols %t | FileCheck %s
; RUN: %if --need=allow_dump --command %p2i -i %s --args -O2 --verbose none \ ; RUN: %if --need=allow_dump --command %p2i -i %s --args -O2 --verbose none \
; RUN: | %if --need=allow_dump --command llvm-mc -triple=i686-none-nacl \ ; RUN: | %if --need=allow_dump --command llvm-mc -triple=i686-nacl \
; RUN: -filetype=obj -o - \ ; RUN: -filetype=obj -o - \
; RUN: | %if --need=allow_dump --command llvm-readobj -file-headers \ ; RUN: | %if --need=allow_dump --command llvm-readobj -file-headers \
; RUN: -sections -section-data -relocations -symbols - \ ; RUN: -sections -section-data -relocations -symbols - \
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
; RUN: %if --need=allow_dump --command \ ; RUN: %if --need=allow_dump --command \
; RUN: %p2i -i %s --args -O2 -ffunction-sections \ ; RUN: %p2i -i %s --args -O2 -ffunction-sections \
; RUN: | %if --need=allow_dump --command \ ; RUN: | %if --need=allow_dump --command \
; RUN: llvm-mc -triple=i686-none-nacl -filetype=obj -o - \ ; RUN: llvm-mc -triple=i686-nacl -filetype=obj -o - \
; RUN: | %if --need=allow_dump --command \ ; RUN: | %if --need=allow_dump --command \
; RUN: llvm-readobj -file-headers -sections -section-data \ ; RUN: llvm-readobj -file-headers -sections -section-data \
; RUN: -relocations -symbols - \ ; RUN: -relocations -symbols - \
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
; RUN: %if --need=allow_dump --command %p2i -i %s --args -O2 \ ; RUN: %if --need=allow_dump --command %p2i -i %s --args -O2 \
; RUN: | %if --need=allow_dump --command \ ; RUN: | %if --need=allow_dump --command \
; RUN: llvm-mc -triple=i686-none-nacl -filetype=obj -o - \ ; RUN: llvm-mc -triple=i686-nacl -filetype=obj -o - \
; RUN: | %if --need=allow_dump --command \ ; RUN: | %if --need=allow_dump --command \
; RUN: llvm-readobj -file-headers -sections -section-data \ ; RUN: llvm-readobj -file-headers -sections -section-data \
; RUN: -relocations -symbols - \ ; RUN: -relocations -symbols - \
......
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
; TODO(kschimpf) Find out why lc2i is needed. ; TODO(kschimpf) Find out why lc2i is needed.
; RUN: %lc2i -i %s --args -O2 --verbose regalloc ; RUN: %lc2i -i %s --args -O2 --verbose regalloc
; ModuleID = 'bugpoint-reduced-simplified.ll'
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 = "i386-pc-linux-gnu"
define void @foo() { define void @foo() {
bb: bb:
br i1 undef, label %bb13, label %bb14 br i1 undef, label %bb13, label %bb14
......
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals \ ; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals \
; RUN: -prefix Subzero_ | FileCheck --check-prefix=CROSS %s ; RUN: -prefix Subzero_ | FileCheck --check-prefix=CROSS %s
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 = "i686-pc-linux-gnu"
@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK: @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 ; CHECK: @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
......
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