This revision was automatically updated to reflect the committed changes.
Closed by commit rTb983131b7e46: [test-suite] Add tests for FP classification 
intrinsics (authored by sepavloff).

Repository:
  rT test-suite

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D106804/new/

https://reviews.llvm.org/D106804

Files:
  SingleSource/UnitTests/CMakeLists.txt
  SingleSource/UnitTests/Float/CMakeLists.txt
  SingleSource/UnitTests/Float/Makefile
  SingleSource/UnitTests/Float/check-helper.h
  SingleSource/UnitTests/Float/classify-f32.h
  SingleSource/UnitTests/Float/classify-f64.h
  SingleSource/UnitTests/Float/classify-ldouble.h
  SingleSource/UnitTests/Float/classify.c
  SingleSource/UnitTests/Float/classify.reference_output
  SingleSource/UnitTests/Float/fformat.h

Index: SingleSource/UnitTests/Float/fformat.h
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/fformat.h
@@ -0,0 +1,65 @@
+//===--- fformat.h - Descriptions of floating point formats -------*- 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 header file contains some macro definitions useful for working with bit
+// accurate floating point representations.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _FFORMAT_H_
+#define _FFORMAT_H_
+
+#define F32_SIGN_BIT        0x80000000U
+#define F32_EXP_MASK        0x7F800000U
+#define F32_MANTISSA_MASK   0x007FFFFFU
+#define F32_MANTISSA_MSB    0x00400000U
+#define F32_QNAN_BIT        F32_MANTISSA_MSB
+#define F32_PAYLOAD_MASK    (F32_MANTISSA_MASK & ~F32_QNAN_BIT)
+#define F32_SIGN_SHIFT      31
+#define F32_EXP_SHIFT       23
+#define F32_EXP_SIZE        (F32_SIGN_SHIFT - F32_EXP_SHIFT)
+#define F32_MANTISSA_SIZE   F32_EXP_SHIFT
+#define F32_EXP_BIAS        127
+#define F32_EXP_MIN         (-126)
+#define F32_EXP_MAX         127
+#define F32_EXP(e)          (((e) + F32_EXP_BIAS) << F32_EXP_SHIFT)
+#define F32_MANTISSA(b1, b2, b3)                                               \
+    (((b1) ? F32_MANTISSA_MSB : 0) |                                           \
+     ((b2) ? (F32_MANTISSA_MSB >> 1) : 0) |                                    \
+     ((b3) ? (F32_MANTISSA_MSB >> 2) : 0))
+#define F32_MAKE(s, e, m)                                                      \
+    (((s) ? F32_SIGN_BIT : 0) |                                                \
+     ((e) & F32_EXP_MASK) |                                                    \
+     ((m) & F32_MANTISSA_MASK))
+#define F32_NORMAL(s, e, m) F32_MAKE((s), F32_EXP(e), (m))
+
+
+#define F64_SIGN_BIT        0x8000000000000000ULL
+#define F64_EXP_MASK        0x7FF0000000000000ULL
+#define F64_MANTISSA_MASK   0x000FFFFFFFFFFFFFULL
+#define F64_MANTISSA_MSB    0x0008000000000000ULL
+#define F64_QNAN_BIT        F64_MANTISSA_MSB
+#define F64_PAYLOAD_MASK    (F64_MANTISSA_MASK & ~F64_QNAN_BIT)
+#define F64_SIGN_SHIFT      63
+#define F64_EXP_SHIFT       52
+#define F64_EXP_SIZE        (F64_SIGN_SHIFT - F64_EXP_SHIFT)
+#define F64_MANTISSA_SIZE   F64_EXP_SHIFT
+#define F64_EXP_BIAS        1023
+#define F64_EXP_MIN         (-1022)
+#define F64_EXP_MAX         1023
+#define F64_EXP(e)          (((uint64_t)(e) + F64_EXP_BIAS) << F64_EXP_SHIFT)
+#define F64_MANTISSA(b1, b2, b3)                                               \
+    (((b1) ? F64_MANTISSA_MSB : 0) |                                           \
+     ((b2) ? (F64_MANTISSA_MSB >> 1) : 0) |                                    \
+     ((b3) ? (F64_MANTISSA_MSB >> 2) : 0))
+#define F64_MAKE(s, e, m)                                                      \
+    (((s) ? F64_SIGN_BIT : 0) |                                                \
+     ((e) & F64_EXP_MASK) |                                                    \
+     ((m) & F64_MANTISSA_MASK))
+#define F64_NORMAL(s, e, m) F64_MAKE((s), F64_EXP(e), (m))
+
+#endif
Index: SingleSource/UnitTests/Float/classify.reference_output
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/classify.reference_output
@@ -0,0 +1 @@
+exit 0
Index: SingleSource/UnitTests/Float/classify.c
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/classify.c
@@ -0,0 +1,26 @@
+//===--- classify.cpp - Tess for FP classification intrinsics ---*- 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 is a general test for floating point classification intrinsic.
+//
+//===----------------------------------------------------------------------===//
+
+#include "classify-f32.h"
+#include "classify-f64.h"
+#include "classify-ldouble.h"
+
+
+int main()
+{
+  test_float();
+  test_double();
+  prepare_ldouble_tables();
+  test_ldouble();
+  return 0;
+}
+
Index: SingleSource/UnitTests/Float/classify-ldouble.h
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/classify-ldouble.h
@@ -0,0 +1,121 @@
+//===--- classify-ldouble.h - Tests for 'long double' -------------*- 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 'long double' type.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _CLASSIFY_LDOUBLE_H_
+#define _CLASSIFY_LDOUBLE_H_
+
+#include "check-helper.h"
+#include <float.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+// The type long double does not have definite representation, it may be mapped
+// to various float types. So instead of preparing bit patterns, rely on builtin
+// functions and macro definitions provided by the compiler.
+
+long double LongDoubleNaNValues[8];
+#ifdef __LDBL_HAS_INFINITY__
+long double LongDoubleInfValues[2];
+#endif
+long double LongDoubleZeroValues[] = { 0.0L, -0.0L};
+#ifdef __LDBL_HAS_DENORM__
+long double LongDoubleDenormValues[2];
+#endif
+long double LongDoubleNormalValues[6];
+
+#define FLOAT_FORMAT "Lg"
+#define VAL_FORMAT   FLOAT_FORMAT
+#define FLOAT_TYPE   long double
+
+void prepare_ldouble_tables() {
+  LongDoubleNaNValues[0] = __builtin_nanl("");
+  LongDoubleNaNValues[1] = -__builtin_nanl("");
+  LongDoubleNaNValues[2] = __builtin_nanl("0x01");
+  LongDoubleNaNValues[3] = -__builtin_nanl("0x01");
+  LongDoubleNaNValues[4] = __builtin_nansl("");
+  LongDoubleNaNValues[5] = -__builtin_nansl("");
+  LongDoubleNaNValues[6] = __builtin_nansl("0x01");
+  LongDoubleNaNValues[7] = -__builtin_nansl("0x01");
+
+#ifdef __LDBL_HAS_INFINITY__
+  LongDoubleInfValues[0] = __builtin_infl();
+  LongDoubleInfValues[1] = -__builtin_infl();
+#endif
+#ifdef __LDBL_HAS_DENORM__
+  LongDoubleDenormValues[0] = __LDBL_DENORM_MIN__;
+  LongDoubleDenormValues[1] = -__LDBL_DENORM_MIN__;
+#endif
+
+  LongDoubleNormalValues[0] = 1.0L;
+  LongDoubleNormalValues[1] = -1.0L;
+  LongDoubleNormalValues[2] = __LDBL_MAX__;
+  LongDoubleNormalValues[3] = -__LDBL_MAX__;
+  LongDoubleNormalValues[4] = __LDBL_MIN__;
+  LongDoubleNormalValues[5] = -__LDBL_MIN__;
+}
+
+int test_ldouble() {
+  for (unsigned i = 0; i < DimOf(LongDoubleNaNValues); i++) {
+    long double X = LongDoubleNaNValues[i];
+    CHECK_VALUE(__builtin_isnan(X), X);
+    CHECK_VALUE(!__builtin_isinf(X), X);
+    CHECK_VALUE(!__builtin_isfinite(X), X);
+    CHECK_VALUE(!__builtin_isnormal(X), X);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, X);
+  }
+#ifdef __LDBL_HAS_INFINITY__
+  for (unsigned i = 0; i < DimOf(LongDoubleInfValues); i++) {
+    long double X = LongDoubleInfValues[i];
+    CHECK_VALUE(!__builtin_isnan(X), X);
+    CHECK_VALUE(__builtin_isinf(X), X);
+    CHECK_VALUE(!__builtin_isfinite(X), X);
+    CHECK_VALUE(!__builtin_isnormal(X), X);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, X);
+  }
+#endif
+  for (unsigned i = 0; i < DimOf(LongDoubleZeroValues); i++) {
+    long double X = LongDoubleZeroValues[i];
+    CHECK_VALUE(!__builtin_isnan(X), X);
+    CHECK_VALUE(!__builtin_isinf(X), X);
+    CHECK_VALUE(__builtin_isfinite(X), X);
+    CHECK_VALUE(!__builtin_isnormal(X), X);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, X);
+  }
+#ifdef __LDBL_HAS_DENORM__
+  for (unsigned i = 0; i < DimOf(LongDoubleDenormValues); i++) {
+     long double X = LongDoubleDenormValues[i];
+    CHECK_VALUE(!__builtin_isnan(X), X);
+    CHECK_VALUE(!__builtin_isinf(X), X);
+    CHECK_VALUE(__builtin_isfinite(X), X);
+    CHECK_VALUE(!__builtin_isnormal(X), X);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, X);
+  }
+#endif
+  for (unsigned i = 0; i < DimOf(LongDoubleNormalValues); i++) {
+    long double X = LongDoubleNormalValues[i];
+    CHECK_VALUE(!__builtin_isnan(X), X);
+    CHECK_VALUE(!__builtin_isinf(X), X);
+    CHECK_VALUE(__builtin_isfinite(X), X);
+    CHECK_VALUE(__builtin_isnormal(X), X);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, X);
+  }
+
+  return 0;
+}
+
+#undef FLOAT_FORMAT
+#undef VAL_FORMAT
+#undef FLOAT_TYPE
+
+#endif
Index: SingleSource/UnitTests/Float/classify-f64.h
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/classify-f64.h
@@ -0,0 +1,184 @@
+//===--- classify-f64.h - Tests for 'double' 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 'double' type.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _CLASSIFY_F64_H_
+#define _CLASSIFY_F64_H_
+
+#include "check-helper.h"
+#include "fformat.h"
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define INT_FORMAT   PRIx64
+#define FLOAT_FORMAT "g"
+#define VAL_FORMAT   INT_FORMAT
+#define INT_TYPE     uint64_t
+#define FLOAT_TYPE   double
+
+uint64_t DoubleNaNValues[] = {
+    F64_MAKE(0, F64_EXP_MASK,                F64_PAYLOAD_MASK),
+    F64_MAKE(1, F64_EXP_MASK,                F64_PAYLOAD_MASK),
+    F64_MAKE(0, F64_EXP_MASK, F64_QNAN_BIT | F64_PAYLOAD_MASK),
+    F64_MAKE(1, F64_EXP_MASK, F64_QNAN_BIT | F64_PAYLOAD_MASK),
+
+    F64_MAKE(0, F64_EXP_MASK, F64_QNAN_BIT),
+    F64_MAKE(1, F64_EXP_MASK, F64_QNAN_BIT),
+
+    F64_MAKE(0, F64_EXP_MASK, F64_QNAN_BIT | 0x0004000000000000ULL),
+    F64_MAKE(1, F64_EXP_MASK, F64_QNAN_BIT | 0x0002000000000000ULL),
+    F64_MAKE(0, F64_EXP_MASK,                0x0004000000000000ULL),
+    F64_MAKE(1, F64_EXP_MASK,                0x0002000000000000ULL),
+
+    F64_MAKE(0, F64_EXP_MASK, F64_QNAN_BIT | 0x0002000000000000ULL),
+    F64_MAKE(1, F64_EXP_MASK, F64_QNAN_BIT | 0x0004000000000000ULL),
+    F64_MAKE(0, F64_EXP_MASK,                0x0000000000000001ULL),
+    F64_MAKE(1, F64_EXP_MASK,                0x0000000000000002ULL)
+};
+
+uint64_t DoubleInfValues[] = {
+    F64_MAKE(0, F64_EXP_MASK, 0),    // +Inf
+    F64_MAKE(1, F64_EXP_MASK, 0)     // -Inf
+};
+
+uint64_t DoubleZeroValues[] = {
+    F64_MAKE(0, 0, 0),    // +0.0
+    F64_MAKE(1, 0, 0)     // -0.0
+};
+
+uint64_t DoubleDenormValues[] = {
+  F64_MAKE(0, 0, 1),                   // smallest positive denornal
+  F64_MAKE(1, 0, 1),                   // smallest negative denornal
+  F64_MAKE(0, 0, F64_MANTISSA_MASK),   // largest positive denormal
+  F64_MAKE(1, 0, F64_MANTISSA_MASK)    // largest negative denormal
+};
+
+uint64_t DoubleNormalValues[] = {
+  F64_NORMAL(0, F64_EXP_MIN, 0),                  // smallest positive normal
+  F64_NORMAL(1, F64_EXP_MIN, 0),                  // smallest negative normal
+  F64_NORMAL(0, F64_EXP_MAX, F64_MANTISSA_MASK),  // largest positive normal
+  F64_NORMAL(1, F64_EXP_MAX, F64_MANTISSA_MASK),  // largest negative normal
+
+  F64_NORMAL(0,  0, 0),                         // +1
+  F64_NORMAL(0, -1, F64_MANTISSA_MASK),         // largest number less than 1
+  F64_NORMAL(0,  0, 1),                         // smallest number larger than 1
+  F64_NORMAL(0,  0, F64_MANTISSA(1, 0, 0)),     // +1.5
+  F64_NORMAL(0,  0, F64_MANTISSA(0, 1, 0)),     // +1.25
+  F64_NORMAL(0,  0, F64_MANTISSA(0, 0, 1)),     // +1.125
+  F64_NORMAL(0, -1, 0),                         // +0.5
+  F64_NORMAL(0, -2, 0),                         // +0.25
+  F64_NORMAL(0, -3, 0),                         // +0.125
+
+  F64_NORMAL(1,  0, 0),                         // -1
+  F64_NORMAL(1, -1, F64_MANTISSA_MASK),
+  F64_NORMAL(1,  0, 1),
+  F64_NORMAL(1,  0, F64_MANTISSA(1, 0, 0)),     // -1.5
+  F64_NORMAL(1,  0, F64_MANTISSA(0, 1, 0)),     // -1.25
+  F64_NORMAL(1,  0, F64_MANTISSA(0, 0, 1)),     // -1.125
+  F64_NORMAL(1, -1, 0),                         // -0.5
+  F64_NORMAL(1, -2, 0),                         // -0.25
+  F64_NORMAL(1, -3, 0),                         // -0.125
+
+  F64_NORMAL(0, 1, 0),                          // 2
+  F64_NORMAL(0, 1, F64_MANTISSA(1, 0, 0)),      // 3
+  F64_NORMAL(1, 1, 0),                          // -2
+  F64_NORMAL(1, 1, F64_MANTISSA(1, 0, 0))       // -3
+};
+
+int test_double() {
+  CHECK_EQ(F64_NORMAL(0,  0, 0), 1.0);
+  CHECK_EQ(F64_NORMAL(0,  0, F64_MANTISSA(1, 0, 0)), 1.5);
+  CHECK_EQ(F64_NORMAL(0,  0, F64_MANTISSA(0, 1, 0)), 1.25);
+  CHECK_EQ(F64_NORMAL(0,  0, F64_MANTISSA(0, 0, 1)), 1.125);
+  CHECK_EQ(F64_NORMAL(0, -1, 0), 0.5);
+  CHECK_EQ(F64_NORMAL(0, -2, 0), 0.25);
+  CHECK_EQ(F64_NORMAL(0, -3, 0), 0.125);
+  CHECK_EQ(F64_NORMAL(0, 1, 0), 2.0);
+  CHECK_EQ(F64_NORMAL(0, 1, F64_MANTISSA(1, 0, 0)), 3.0);
+
+  CHECK_EQ(F64_NORMAL(1,  0, 0), -1.0);
+  CHECK_EQ(F64_NORMAL(1,  0, F64_MANTISSA(1, 0, 0)), -1.5);
+  CHECK_EQ(F64_NORMAL(1,  0, F64_MANTISSA(0, 1, 0)), -1.25);
+  CHECK_EQ(F64_NORMAL(1,  0, F64_MANTISSA(0, 0, 1)), -1.125);
+  CHECK_EQ(F64_NORMAL(1, -1, 0), -0.5);
+  CHECK_EQ(F64_NORMAL(1, -2, 0), -0.25);
+  CHECK_EQ(F64_NORMAL(1, -3, 0), -0.125);
+  CHECK_EQ(F64_NORMAL(1, 1, 0), -2.0);
+  CHECK_EQ(F64_NORMAL(1, 1, F64_MANTISSA(1, 0, 0)), -3.0);
+
+  CHECK_EQ(F64_NORMAL(0, F64_EXP_MIN, 0), 2.2250738585072014e-308);
+  CHECK_EQ(F64_NORMAL(1, F64_EXP_MIN, 0), -2.2250738585072014e-308);
+  CHECK_EQ(F64_NORMAL(0, F64_EXP_MAX, F64_MANTISSA_MASK), 1.7976931348623157e+308);
+  CHECK_EQ(F64_NORMAL(1, F64_EXP_MAX, F64_MANTISSA_MASK), -1.7976931348623157e+308);
+
+  for (unsigned i = 0; i < DimOf(DoubleNaNValues); i++) {
+    uint64_t *IPtr = DoubleNaNValues + i;
+    uint64_t IX = *IPtr;
+    double X = *(double *)IPtr;
+    CHECK_VALUE(__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(!__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX);
+  }
+  for (unsigned i = 0; i < DimOf(DoubleInfValues); i++) {
+    uint64_t *IPtr = DoubleInfValues + i;
+    uint64_t IX = *IPtr;
+    double X = *(double *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(__builtin_isinf(X), IX);
+    CHECK_VALUE(!__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IX);
+  }
+  for (unsigned i = 0; i < DimOf(DoubleZeroValues); i++) {
+    uint64_t *IPtr = DoubleZeroValues + i;
+    uint64_t IX = *IPtr;
+    double X = *(double *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IX);
+  }
+  for (unsigned i = 0; i < DimOf(DoubleDenormValues); i++) {
+    uint64_t *IPtr = DoubleDenormValues + i;
+    uint64_t IX = *IPtr;
+    double X = *(double *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IX);
+  }
+  for (unsigned i = 0; i < DimOf(DoubleNormalValues); i++) {
+    uint64_t *IPtr = DoubleNormalValues + i;
+    uint64_t IX = *IPtr;
+    double X = *(double *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IX);
+  }
+
+  return 0;
+}
+
+#undef INT_FORMAT
+#undef FLOAT_FORMAT
+#undef VAL_FORMAT
+#undef INT_TYPE
+#undef FLOAT_TYPE
+
+#endif
Index: SingleSource/UnitTests/Float/classify-f32.h
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/classify-f32.h
@@ -0,0 +1,184 @@
+//===--- 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 INT_FORMAT   PRIx32
+#define FLOAT_FORMAT "g"
+#define VAL_FORMAT   INT_FORMAT
+#define INT_TYPE     uint32_t
+#define FLOAT_TYPE   float
+
+uint32_t FloatNaNValues[] = {
+    F32_MAKE(0, F32_EXP_MASK,                F32_PAYLOAD_MASK),
+    F32_MAKE(1, F32_EXP_MASK,                F32_PAYLOAD_MASK),
+    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,                0x00200000U),
+    F32_MAKE(1, F32_EXP_MASK,                0x00100000U),
+
+    F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | 0x00000001U),
+    F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00000002U),
+    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() {
+  CHECK_EQ(F32_NORMAL(0,  0, 0), 1.0F);
+  CHECK_EQ(F32_NORMAL(0,  0, F32_MANTISSA(1, 0, 0)), 1.5F);
+  CHECK_EQ(F32_NORMAL(0,  0, F32_MANTISSA(0, 1, 0)), 1.25F);
+  CHECK_EQ(F32_NORMAL(0,  0, F32_MANTISSA(0, 0, 1)), 1.125);
+  CHECK_EQ(F32_NORMAL(0, -1, 0), 0.5F);
+  CHECK_EQ(F32_NORMAL(0, -2, 0), 0.25);
+  CHECK_EQ(F32_NORMAL(0, -3, 0), 0.125);
+  CHECK_EQ(F32_NORMAL(0, 1, 0), 2.0F);
+  CHECK_EQ(F32_NORMAL(0, 1, F32_MANTISSA(1, 0, 0)), 3.0F);
+
+  CHECK_EQ(F32_NORMAL(1,  0, 0), -1.0F);
+  CHECK_EQ(F32_NORMAL(1,  0, F32_MANTISSA(1, 0, 0)), -1.5F);
+  CHECK_EQ(F32_NORMAL(1,  0, F32_MANTISSA(0, 1, 0)), -1.25F);
+  CHECK_EQ(F32_NORMAL(1,  0, F32_MANTISSA(0, 0, 1)), -1.125);
+  CHECK_EQ(F32_NORMAL(1, -1, 0), -0.5F);
+  CHECK_EQ(F32_NORMAL(1, -2, 0), -0.25);
+  CHECK_EQ(F32_NORMAL(1, -3, 0), -0.125);
+  CHECK_EQ(F32_NORMAL(1, 1, 0), -2.0F);
+  CHECK_EQ(F32_NORMAL(1, 1, F32_MANTISSA(1, 0, 0)), -3.0F);
+
+  CHECK_EQ(F32_NORMAL(0, F32_EXP_MIN, 0), 1.1754943508e-38F);
+  CHECK_EQ(F32_NORMAL(1, F32_EXP_MIN, 0), -1.1754943508e-38F);
+  CHECK_EQ(F32_NORMAL(0, F32_EXP_MAX, F32_MANTISSA_MASK), 3.4028234664e38F);
+  CHECK_EQ(F32_NORMAL(1, F32_EXP_MAX, F32_MANTISSA_MASK), -3.4028234664e38F);
+
+  for (unsigned i = 0; i < DimOf(FloatNaNValues); i++) {
+    uint32_t *IPtr = FloatNaNValues + i;
+    uint32_t IX = *IPtr;
+    float X = *(float *)IPtr;
+    CHECK_VALUE(__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(!__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX);
+  }
+  for (unsigned i = 0; i < DimOf(FloatInfValues); i++) {
+    uint32_t *IPtr = FloatInfValues + i;
+    uint32_t IX = *IPtr;
+    float X = *(float *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(__builtin_isinf(X), IX);
+    CHECK_VALUE(!__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IX);
+  }
+  for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) {
+    uint32_t *IPtr = FloatZeroValues + i;
+    uint32_t IX = *IPtr;
+    float X = *(float *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IX);
+  }
+  for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) {
+    uint32_t *IPtr = FloatDenormValues + i;
+    uint32_t IX = *IPtr;
+    float X = *(float *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(!__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IX);
+  }
+  for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) {
+    uint32_t *IPtr = FloatNormalValues + i;
+    uint32_t IX = *IPtr;
+    float X = *(float *)IPtr;
+    CHECK_VALUE(!__builtin_isnan(X), IX);
+    CHECK_VALUE(!__builtin_isinf(X), IX);
+    CHECK_VALUE(__builtin_isfinite(X), IX);
+    CHECK_VALUE(__builtin_isnormal(X), IX);
+    CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IX);
+  }
+
+  return 0;
+}
+
+#undef INT_FORMAT
+#undef FLOAT_FORMAT
+#undef VAL_FORMAT
+#undef INT_TYPE
+#undef FLOAT_TYPE
+
+#endif
Index: SingleSource/UnitTests/Float/check-helper.h
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/check-helper.h
@@ -0,0 +1,60 @@
+//===--- check-helper.h - Helper stuff for tests ------------------*- 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 header file contains helper macros for making tests for floating point
+// operations.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _CHECK_HELPER_H_
+#define _CHECK_HELPER_H_
+
+#define DimOf(x) (sizeof(x) / sizeof(x[0]))
+
+// Checks if condition 'cond' is true for the 'value'.
+//
+// Requires the following macros to be defined:
+//
+//     VAL_FORMAT - printf format specifier without %, like "d" or "llx", which
+//                  should be used to print 'value'.
+//
+#define CHECK_VALUE(cond, value)                                               \
+    do {                                                                       \
+      if (!cond) {                                                             \
+        printf("Check '%s' in file '%s' at line %d "                           \
+               "failed for the value '%" VAL_FORMAT "'\n",                     \
+               #cond, __FILE__, __LINE__, value);                              \
+        exit(-1);                                                              \
+      }                                                                        \
+    } while(0)
+
+// Checks if floating point 'value' is equal to the value 'expected' which is an
+// integer that represents bits of floating point number.
+//
+// Requires the following macros to be defined:
+//
+//     INT_FORMAT   - printf format specifier without %, like "d" or "llx",
+//                    which should be used to print 'expected'.
+//     FLOAT_FORMAT - printf format specifier without % to print 'value'.
+//     INT_TYPE     - type of 'expected'.
+//     FLOAT_TYPE   - type of 'value'.
+//
+#define CHECK_EQ(value, expected)                                              \
+    do {                                                                       \
+      union {                                                                  \
+        INT_TYPE i;                                                            \
+        FLOAT_TYPE f;                                                          \
+      } u;                                                                     \
+      u.i = value;                                                             \
+      if (u.f != expected) {                                                   \
+         printf("Check in file '%s' at line %d failed: "                       \
+                "'%" INT_FORMAT "' != '%" FLOAT_FORMAT "'\n",                  \
+                __FILE__, __LINE__, value, expected);                          \
+        exit(-1);                                                              \
+      }                                                                        \
+    } while(0)
+#endif
Index: SingleSource/UnitTests/Float/Makefile
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/Makefile
@@ -0,0 +1,7 @@
+# SingleSource/UnitTests/Float/Makefile
+
+DIRS =
+LEVEL = ../../..
+include $(LEVEL)/SingleSource/Makefile.singlesrc
+
+
Index: SingleSource/UnitTests/Float/CMakeLists.txt
===================================================================
--- /dev/null
+++ SingleSource/UnitTests/Float/CMakeLists.txt
@@ -0,0 +1 @@
+llvm_singlesource()
Index: SingleSource/UnitTests/CMakeLists.txt
===================================================================
--- SingleSource/UnitTests/CMakeLists.txt
+++ SingleSource/UnitTests/CMakeLists.txt
@@ -1,6 +1,7 @@
 include(CheckCCompilerFlag)
 
 add_subdirectory(C++11)
+add_subdirectory(Float)
 add_subdirectory(SignlessTypes)
 add_subdirectory(Threads)
 add_subdirectory(Vector)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to