Peter Smith a98efd2b81 [builtins][ARM] re-enable mulsc3_test.c on Arm
The mulsc3_test.c was marked as unsupported due to PR32457, the underlying
cause of this PR was fixed in PR28164 so we can remove the unsupported as
it is no longer needed.

Differential Revision: https://reviews.llvm.org/D40076

llvm-svn: 318396
2017-11-16 13:00:17 +00:00

375 lines
7.5 KiB
C

// RUN: %clang_builtins %s %librt -lm -o %t && %run %t
//===-- mulsc3_test.c - Test __mulsc3 -------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file tests __mulsc3 for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
#include <math.h>
#include <complex.h>
#include <stdio.h>
// REQUIRES: c99-complex
// Returns: the product of a + ib and c + id
COMPILER_RT_ABI float _Complex
__mulsc3(float __a, float __b, float __c, float __d);
enum {zero, non_zero, inf, NaN, non_zero_nan};
int
classify(float _Complex x)
{
if (x == 0)
return zero;
if (isinf(crealf(x)) || isinf(cimagf(x)))
return inf;
if (isnan(crealf(x)) && isnan(cimagf(x)))
return NaN;
if (isnan(crealf(x)))
{
if (cimagf(x) == 0)
return NaN;
return non_zero_nan;
}
if (isnan(cimagf(x)))
{
if (crealf(x) == 0)
return NaN;
return non_zero_nan;
}
return non_zero;
}
int test__mulsc3(float a, float b, float c, float d)
{
float _Complex r = __mulsc3(a, b, c, d);
// printf("test__mulsc3(%f, %f, %f, %f) = %f + I%f\n",
// a, b, c, d, crealf(r), cimagf(r));
float _Complex dividend;
float _Complex divisor;
__real__ dividend = a;
__imag__ dividend = b;
__real__ divisor = c;
__imag__ divisor = d;
switch (classify(dividend))
{
case zero:
switch (classify(divisor))
{
case zero:
if (classify(r) != zero)
return 1;
break;
case non_zero:
if (classify(r) != zero)
return 1;
break;
case inf:
if (classify(r) != NaN)
return 1;
break;
case NaN:
if (classify(r) != NaN)
return 1;
break;
case non_zero_nan:
if (classify(r) != NaN)
return 1;
break;
}
break;
case non_zero:
switch (classify(divisor))
{
case zero:
if (classify(r) != zero)
return 1;
break;
case non_zero:
if (classify(r) != non_zero)
return 1;
{
float _Complex z = a * c - b * d + _Complex_I*(a * d + b * c);
// relaxed tolerance to arbitrary (1.e-6) amount.
if (cabsf((r-z)/r) > 1.e-6)
return 1;
}
break;
case inf:
if (classify(r) != inf)
return 1;
break;
case NaN:
if (classify(r) != NaN)
return 1;
break;
case non_zero_nan:
if (classify(r) != NaN)
return 1;
break;
}
break;
case inf:
switch (classify(divisor))
{
case zero:
if (classify(r) != NaN)
return 1;
break;
case non_zero:
if (classify(r) != inf)
return 1;
break;
case inf:
if (classify(r) != inf)
return 1;
break;
case NaN:
if (classify(r) != NaN)
return 1;
break;
case non_zero_nan:
if (classify(r) != inf)
return 1;
break;
}
break;
case NaN:
switch (classify(divisor))
{
case zero:
if (classify(r) != NaN)
return 1;
break;
case non_zero:
if (classify(r) != NaN)
return 1;
break;
case inf:
if (classify(r) != NaN)
return 1;
break;
case NaN:
if (classify(r) != NaN)
return 1;
break;
case non_zero_nan:
if (classify(r) != NaN)
return 1;
break;
}
break;
case non_zero_nan:
switch (classify(divisor))
{
case zero:
if (classify(r) != NaN)
return 1;
break;
case non_zero:
if (classify(r) != NaN)
return 1;
break;
case inf:
if (classify(r) != inf)
return 1;
break;
case NaN:
if (classify(r) != NaN)
return 1;
break;
case non_zero_nan:
if (classify(r) != NaN)
return 1;
break;
}
break;
}
return 0;
}
float x[][2] =
{
{ 1.e-6, 1.e-6},
{-1.e-6, 1.e-6},
{-1.e-6, -1.e-6},
{ 1.e-6, -1.e-6},
{ 1.e+6, 1.e-6},
{-1.e+6, 1.e-6},
{-1.e+6, -1.e-6},
{ 1.e+6, -1.e-6},
{ 1.e-6, 1.e+6},
{-1.e-6, 1.e+6},
{-1.e-6, -1.e+6},
{ 1.e-6, -1.e+6},
{ 1.e+6, 1.e+6},
{-1.e+6, 1.e+6},
{-1.e+6, -1.e+6},
{ 1.e+6, -1.e+6},
{NAN, NAN},
{-INFINITY, NAN},
{-2, NAN},
{-1, NAN},
{-0.5, NAN},
{-0., NAN},
{+0., NAN},
{0.5, NAN},
{1, NAN},
{2, NAN},
{INFINITY, NAN},
{NAN, -INFINITY},
{-INFINITY, -INFINITY},
{-2, -INFINITY},
{-1, -INFINITY},
{-0.5, -INFINITY},
{-0., -INFINITY},
{+0., -INFINITY},
{0.5, -INFINITY},
{1, -INFINITY},
{2, -INFINITY},
{INFINITY, -INFINITY},
{NAN, -2},
{-INFINITY, -2},
{-2, -2},
{-1, -2},
{-0.5, -2},
{-0., -2},
{+0., -2},
{0.5, -2},
{1, -2},
{2, -2},
{INFINITY, -2},
{NAN, -1},
{-INFINITY, -1},
{-2, -1},
{-1, -1},
{-0.5, -1},
{-0., -1},
{+0., -1},
{0.5, -1},
{1, -1},
{2, -1},
{INFINITY, -1},
{NAN, -0.5},
{-INFINITY, -0.5},
{-2, -0.5},
{-1, -0.5},
{-0.5, -0.5},
{-0., -0.5},
{+0., -0.5},
{0.5, -0.5},
{1, -0.5},
{2, -0.5},
{INFINITY, -0.5},
{NAN, -0.},
{-INFINITY, -0.},
{-2, -0.},
{-1, -0.},
{-0.5, -0.},
{-0., -0.},
{+0., -0.},
{0.5, -0.},
{1, -0.},
{2, -0.},
{INFINITY, -0.},
{NAN, 0.},
{-INFINITY, 0.},
{-2, 0.},
{-1, 0.},
{-0.5, 0.},
{-0., 0.},
{+0., 0.},
{0.5, 0.},
{1, 0.},
{2, 0.},
{INFINITY, 0.},
{NAN, 0.5},
{-INFINITY, 0.5},
{-2, 0.5},
{-1, 0.5},
{-0.5, 0.5},
{-0., 0.5},
{+0., 0.5},
{0.5, 0.5},
{1, 0.5},
{2, 0.5},
{INFINITY, 0.5},
{NAN, 1},
{-INFINITY, 1},
{-2, 1},
{-1, 1},
{-0.5, 1},
{-0., 1},
{+0., 1},
{0.5, 1},
{1, 1},
{2, 1},
{INFINITY, 1},
{NAN, 2},
{-INFINITY, 2},
{-2, 2},
{-1, 2},
{-0.5, 2},
{-0., 2},
{+0., 2},
{0.5, 2},
{1, 2},
{2, 2},
{INFINITY, 2},
{NAN, INFINITY},
{-INFINITY, INFINITY},
{-2, INFINITY},
{-1, INFINITY},
{-0.5, INFINITY},
{-0., INFINITY},
{+0., INFINITY},
{0.5, INFINITY},
{1, INFINITY},
{2, INFINITY},
{INFINITY, INFINITY}
};
int main()
{
const unsigned N = sizeof(x) / sizeof(x[0]);
unsigned i, j;
for (i = 0; i < N; ++i)
{
for (j = 0; j < N; ++j)
{
if (test__mulsc3(x[i][0], x[i][1], x[j][0], x[j][1]))
return 1;
}
}
return 0;
}