#!/bin/bash # ULP error check script. # # Copyright (c) 2019-2024, Arm Limited. # SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception #set -x set -eu # cd to bin directory. cd "${0%/*}" rmodes='n u d z' #rmodes=n flags="${ULPFLAGS:--q}" emu="$@" FAIL=0 PASS=0 t() { # First argument: routine name routine=$1; shift # Second and third argument: lo and hi bounds # Extra processing needed for bivariate routines IFS=',' read -ra LO <<< "$1"; shift IFS=',' read -ra HI <<< "$1"; shift ITV="${LO[0]} ${HI[0]}" for i in "${!LO[@]}"; do [[ "$i" -eq "0" ]] || ITV="$ITV x ${LO[$i]} ${HI[$i]}" done # Fourth argument: number of test points n=$1; shift # Any remaining arguments forwards directly to ulp tool extra_flags="$@" # Read ULP limits, fenv expectation and control values from autogenerated files limits_file=$LIMITS [ $r == "n" ] || limits_file=${limits_file}_nn L=$(grep "^$routine " $limits_file | awk '{print $2}') [ -n "$L" ] || { echo ERROR: Could not determine ULP limit for $routine in $limits_file && false; } cvals=($(grep "^$routine " $CVALS | awk '{print $2}')) if grep -q "^$routine$" $DISABLE_FENV; then extra_flags="$extra_flags -f"; fi # Emulate a do-while loop to loop over cvals, but still execute once if it is empty while : ; do # Empty string if we are at the end of cvals array c_arg="" [ -z "${cvals[0]:-}" ] || c_arg="-c ${cvals[0]}" $emu ./ulp -e $L $flags $extra_flags -r $r $c_arg $routine $ITV $n && PASS=$((PASS+1)) || FAIL=$((FAIL+1)) # Shift cvals by 1, and break if it is now empty cvals=("${cvals[@]:1}") [ -n "${cvals[0]:-}" ] || break done # Run ULP tool } check() { $emu ./ulp -f -q "$@" } if [[ $WANT_EXPERIMENTAL_MATH -eq 1 ]] && [[ $WANT_SVE_TESTS -eq 1 ]] && [[ $USE_MPFR -eq 0 ]]; then # No guarantees about powi accuracy, so regression-test for exactness # w.r.t. the custom reference impl in ulp_wrappers.h if [ -z "$FUNC" ] || [ "$FUNC" == "_ZGVsMxvv_powi" ]; then check -q -f -e 0 _ZGVsMxvv_powi 0 inf x 0 1000 100000 check -q -f -e 0 _ZGVsMxvv_powi -0 -inf x 0 1000 100000 check -q -f -e 0 _ZGVsMxvv_powi 0 inf x -0 -1000 100000 check -q -f -e 0 _ZGVsMxvv_powi -0 -inf x -0 -1000 100000 fi if [ -z "$FUNC" ] || [ "$FUNC" == "_ZGVsMxvv_powk" ]; then check -q -f -e 0 _ZGVsMxvv_powk 0 inf x 0 1000 100000 check -q -f -e 0 _ZGVsMxvv_powk -0 -inf x 0 1000 100000 check -q -f -e 0 _ZGVsMxvv_powk 0 inf x -0 -1000 100000 check -q -f -e 0 _ZGVsMxvv_powk -0 -inf x -0 -1000 100000 fi fi # Test generic routines in all rounding modes for r in $rmodes do while read F LO HI N do [[ -z $F ]] || t $F $LO $HI $N done << EOF $(grep "\b$FUNC\b" $GEN_ITVS) EOF done # Only test arch-specific routines in round-to-nearest, with sign of zero ignored (-z flag) r=n while read F LO HI N do [[ -z $F ]] || t $F $LO $HI $N -z done << EOF $(grep "\b$FUNC\b" $ARCH_ITVS) EOF [ 0 -eq $FAIL ] || { echo "FAILED $FAIL PASSED $PASS" exit 1 }