additional test cases for floating point comparison splitting pass
ADD
test/test-fpExtra.sh
+#!/bin/sh
+
+. ./test-pre.sh
+
+test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
+ $ECHO "$GREY[*] llvm_mode laf-intel/compcov testing splitting floating point types with Nan, infinity, minusZero"
+ for testcase in ./test-fp_minusZerocases.c ./test-fp_Infcases.c ./test-fp_NaNcases.c; do
+ #for testcase in ./test-fp_cases.c ./test-fp_Infcases.c ./test-fp_NaNcases.c ./test-fp_minusZerocases.c ; do
+ for I in float double "long double"; do
+ #for I in double; do
+ for BITS in 64 32 16 8; do
+ #for BITS in 64; do
+ bin="$testcase-split-$I-$BITS.compcov"
+#AFL_DONT_OPTIMIZE=1 AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 AFL_LLVM_LAF_SPLIT_FLOATS=1 ../afl-clang-fast -DFLOAT_TYPE="$I" -S "$testcase"
+#AFL_DONT_OPTIMIZE=1 AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 AFL_LLVM_LAF_SPLIT_FLOATS=1 ../afl-clang-fast -DFLOAT_TYPE="$I" -S -emit-llvm "$testcase"
+AFL_DONT_OPTIMIZE=1 AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 AFL_LLVM_LAF_SPLIT_FLOATS=1 ../afl-clang-fast -DFLOAT_TYPE="$I" -o "$bin" "$testcase" > test.out 2>&1;
+ if ! test -e "$bin"; then
+ cat test.out
+ $ECHO "$RED[!] llvm_mode laf-intel/compcov float splitting failed! ($testcase with type $I split to $BITS)!";
+ CODE=1
+ break
+ fi
+ if ! "$bin"; then
+ $ECHO "$RED[!] llvm_mode laf-intel/compcov float splitting resulted in miscompilation (type $I split to $BITS)!";
+ CODE=1
+ break
+ fi
+ rm -f "$bin" test.out || true
+ done
+ done
+ done
+ rm -f test-fp_cases*.compcov test.out
+
+} || {
+ $ECHO "$YELLOW[-] llvm_mode not compiled, cannot test"
+ INCOMPLETE=1
+}
+
+. ./test-post.sh

ADD
test/test-fp_Infcases.c
+/* test cases for floating point comparison transformations
+ * compile with -DFLOAT_TYPE=float
+ * or -DFLOAT_TYPE=double
+ * or -DFLOAT_TYPE="long double"
+ */
+
+#include <assert.h>
+#define _GNU_SOURCE
+#include <math.h> /* for NaNs and infinity values */
+
+int main() {
+
+ volatile FLOAT_TYPE a, b;
+
+#ifdef INFINITY
+ FLOAT_TYPE inf = (FLOAT_TYPE) INFINITY;
+#else
+ FLOAT_TYPE inf = 1.0 / 0.0; /* produces infinity */
+#endif
+ FLOAT_TYPE negZero = 1.0 / -inf;
+ FLOAT_TYPE posZero = 0.0;
+
+ /* plus infinity */
+ a = (1.0 / 0.0); /* positive infinity */
+ b = (1.0 / 0.0); /* positive infinity */
+ assert(!(a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert((a >= b));
+ assert(!(a != b));
+ assert((a == b));
+
+ b = -(1.0 / 0.0); /* negative infinity */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert((a > b));
+ assert((a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert((a > b));
+ assert((a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 0.0; /* positive 0 */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert((a > b));
+ assert((a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = -42.0;
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert((a > b));
+ assert((a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 42.0;
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert((a > b));
+ assert((a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ /* negative infinity */
+ a = -(1.0 / 0.0);
+ b = (1.0 / 0.0); /* positive infinity */
+ assert((a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = -(1.0 / 0.0); /* negative infinity */
+ assert(!(a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert((a >= b));
+ assert(!(a != b));
+ assert((a == b));
+
+ b = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ assert((a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 0.0; /* positive 0 */
+ assert((a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = -42.0;
+ assert((a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 42.0;
+ assert((a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+}
+

ADD
test/test-fp_NaNcases.c
+/* test cases for floating point comparison transformations
+ * compile with -DFLOAT_TYPE=float
+ * or -DFLOAT_TYPE=double
+ * or -DFLOAT_TYPE="long double"
+ */
+
+#include <assert.h>
+#define _GNU_SOURCE
+#include <math.h> /* for NaNs and infinity values */
+
+int main() {
+
+ volatile FLOAT_TYPE a, b;
+
+ /* NaN */
+#ifdef NAN
+ a = (FLOAT_TYPE) NAN; /* produces NaN */
+#else
+ a = 0.0 / 0.0; /* produces NaN */
+#endif
+#ifdef INFINITY
+ FLOAT_TYPE inf = (FLOAT_TYPE) INFINITY;
+#else
+ FLOAT_TYPE inf = 1.0 / 0.0; /* produces infinity */
+#endif
+ FLOAT_TYPE negZero = 1.0 / -inf;
+ FLOAT_TYPE posZero = 0.0;
+ b = a;
+
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 0.0;
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = 42.0;
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = -42.0;
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = (1.0 / 0.0); /* positive infinity */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+ b = -(1.0 / 0.0); /* negative infinity */
+ assert(!(a < b));
+ assert(!(a <= b));
+ assert(!(a > b));
+ assert(!(a >= b));
+ assert((a != b));
+ assert(!(a == b));
+
+}
+

ADD
test/test-fp_minusZerocases.c
+/* test cases for floating point comparison transformations
+ * compile with -DFLOAT_TYPE=float
+ * or -DFLOAT_TYPE=double
+ * or -DFLOAT_TYPE="long double"
+ */
+
+#include <assert.h>
+#define _GNU_SOURCE
+#include <math.h> /* for NaNs and infinity values */
+
+int main() {
+
+ volatile FLOAT_TYPE a, b;
+
+ /* negative zero */
+ a = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ b = 0.0; /* positive 0 */
+ assert(!(a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert((a >= b));
+ assert(!(a != b));
+ assert((a == b));
+
+ a = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ b = 1.0 / -(1.0 / 0.0); /* negative 0 */
+ assert(!(a < b));
+ assert((a <= b));
+ assert(!(a > b));
+ assert((a >= b));
+ assert(!(a != b));
+ assert((a == b));
+
+}
+

additional test cases for floating point comparison splitting pass