blob: 61257fd4055c0d95dd46ff3c08527ba1c36fd9d7 [file] [log] [blame]
//===--- classify-f32.h - Tests for 'float' classification --------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains tests of classification functions for 'float' type.
//
//===----------------------------------------------------------------------===//
#ifndef _CLASSIFY_F32_H_
#define _CLASSIFY_F32_H_
#include "check-helper.h"
#include "fformat.h"
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define VAL_FORMAT "%" PRIx32
#define GET_VALUE(x) (*(uint32_t *)x)
uint32_t FloatQNaNValues[] = {
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | F32_PAYLOAD_MASK),
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | F32_PAYLOAD_MASK),
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT),
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT),
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | 0x00200000U),
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00100000U),
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | 0x00000001U),
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00000002U)};
uint32_t FloatSNaNValues[] = {F32_MAKE(0, F32_EXP_MASK, F32_PAYLOAD_MASK),
F32_MAKE(1, F32_EXP_MASK, F32_PAYLOAD_MASK),
F32_MAKE(0, F32_EXP_MASK, 0x00200000U),
F32_MAKE(1, F32_EXP_MASK, 0x00100000U),
F32_MAKE(0, F32_EXP_MASK, 0x00000001U),
F32_MAKE(1, F32_EXP_MASK, 0x00000002U)};
uint32_t FloatInfValues[] = {
F32_MAKE(0, F32_EXP_MASK, 0), // +Inf
F32_MAKE(1, F32_EXP_MASK, 0) // -Inf
};
uint32_t FloatZeroValues[] = {
F32_MAKE(0, 0, 0), // +0.0
F32_MAKE(1, 0, 0) // -0.0
};
uint32_t FloatDenormValues[] = {
F32_MAKE(0, 0, 1), // smallest positive denornal
F32_MAKE(1, 0, 1), // smallest negative denornal
F32_MAKE(0, 0, F32_MANTISSA_MASK), // largest positive denormal
F32_MAKE(1, 0, F32_MANTISSA_MASK) // largest negative denormal
};
uint32_t FloatNormalValues[] = {
F32_NORMAL(0, F32_EXP_MIN, 0), // smallest positive normal
F32_NORMAL(1, F32_EXP_MIN, 0), // smallest negative normal
F32_NORMAL(0, F32_EXP_MAX, F32_MANTISSA_MASK), // largest positive normal
F32_NORMAL(1, F32_EXP_MAX, F32_MANTISSA_MASK), // largest negative normal
F32_NORMAL(0, 0, 0), // +1
F32_NORMAL(0, -1, F32_MANTISSA_MASK), // largest number less than 1
F32_NORMAL(0, 0, 1), // smallest number larger than 1
F32_NORMAL(0, 0, F32_MANTISSA(1, 0, 0)), // +1.5
F32_NORMAL(0, 0, F32_MANTISSA(0, 1, 0)), // +1.25
F32_NORMAL(0, 0, F32_MANTISSA(0, 0, 1)), // +1.125
F32_NORMAL(0, -1, 0), // +0.5
F32_NORMAL(0, -2, 0), // +0.25
F32_NORMAL(0, -3, 0), // +0.125
F32_NORMAL(1, 0, 0), // -1
F32_NORMAL(1, -1, F32_MANTISSA_MASK),
F32_NORMAL(1, 0, 1),
F32_NORMAL(1, 0, F32_MANTISSA(1, 0, 0)), // -1.5
F32_NORMAL(1, 0, F32_MANTISSA(0, 1, 0)), // -1.25
F32_NORMAL(1, 0, F32_MANTISSA(0, 0, 1)), // -1.125
F32_NORMAL(1, -1, 0), // -0.5
F32_NORMAL(1, -2, 0), // -0.25
F32_NORMAL(1, -3, 0), // -0.125
F32_NORMAL(0, 1, 0), // 2
F32_NORMAL(0, 1, F32_MANTISSA(1, 0, 0)), // 3
F32_NORMAL(1, 1, 0), // -2
F32_NORMAL(1, 1, F32_MANTISSA(1, 0, 0)) // -3
};
int test_float() {
for (unsigned i = 0; i < DimOf(FloatQNaNValues); i++) {
uint32_t *IPtr = FloatQNaNValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(__builtin_isnan(X), IPtr);
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
CHECK_VALUE(!__builtin_isinf(X), IPtr);
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
CHECK_VALUE(!__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IPtr);
}
for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) {
uint32_t *IPtr = FloatSNaNValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(__builtin_isnan(X), IPtr);
CHECK_VALUE(__builtin_issignaling(X), IPtr);
CHECK_VALUE(!__builtin_isinf(X), IPtr);
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
CHECK_VALUE(!__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IPtr);
}
for (unsigned i = 0; i < DimOf(FloatInfValues); i++) {
uint32_t *IPtr = FloatInfValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(!__builtin_isnan(X), IPtr);
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
CHECK_VALUE(__builtin_isinf(X), IPtr);
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
CHECK_VALUE(!__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IPtr);
}
for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) {
uint32_t *IPtr = FloatZeroValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(!__builtin_isnan(X), IPtr);
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
CHECK_VALUE(!__builtin_isinf(X), IPtr);
CHECK_VALUE(__builtin_isfinite(X), IPtr);
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
CHECK_VALUE(__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IPtr);
}
for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) {
uint32_t *IPtr = FloatDenormValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(!__builtin_isnan(X), IPtr);
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
CHECK_VALUE(!__builtin_isinf(X), IPtr);
CHECK_VALUE(__builtin_isfinite(X), IPtr);
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
CHECK_VALUE(__builtin_issubnormal(X), IPtr);
CHECK_VALUE(!__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IPtr);
}
for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) {
uint32_t *IPtr = FloatNormalValues + i;
float X = *(float *)IPtr;
CHECK_VALUE(!__builtin_isnan(X), IPtr);
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
CHECK_VALUE(!__builtin_isinf(X), IPtr);
CHECK_VALUE(__builtin_isfinite(X), IPtr);
CHECK_VALUE(__builtin_isnormal(X), IPtr);
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
CHECK_VALUE(!__builtin_iszero(X), IPtr);
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IPtr);
}
return 0;
}
#define FLOAT_TYPE float
#include "gen_isfpclass_funcs.h"
void test_isfpclass_float() {
for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) {
float X = *(float *)(FloatZeroValues + i);
if (__builtin_signbit(X) == 0)
test_fcPosZero_float(X);
else
test_fcNegZero_float(X);
}
for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) {
float X = *(float *)(FloatDenormValues + i);
if (X < 0)
test_fcNegSubnormal_float(X);
else
test_fcPosSubnormal_float(X);
}
for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) {
float X = *(float *)(FloatNormalValues + i);
if (X < 0)
test_fcNegNormal_float(X);
else
test_fcPosNormal_float(X);
}
for (unsigned i = 0; i < DimOf(FloatInfValues); i++) {
float X = *(float *)(FloatInfValues + i);
if (X > 0)
test_fcPosInf_float(X);
else
test_fcNegInf_float(X);
}
for (unsigned i = 0; i < DimOf(FloatQNaNValues); i++) {
float X = *(float *)(FloatQNaNValues + i);
test_fcQNan_float(X);
}
for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) {
float X = *(float *)(FloatSNaNValues + i);
test_fcSNan_float(X);
}
test_fcPosInf_float(__builtin_inff());
test_fcNegInf_float(-__builtin_inff());
test_fcPosZero_float(0.0F);
test_fcNegZero_float(-0.0F);
}
#undef VAL_FORMAT
#undef GET_VALUE
#undef FLOAT_TYPE
#endif