brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · e7cac46 Raw
364 lines · c
1// RUN: %clang_builtins %s %librt -lm -o %t && %run %t2// REQUIRES: librt_has_mulsc33// REQUIRES: c99-complex4 5#include "int_lib.h"6#include <math.h>7#include <complex.h>8#include <stdio.h>9 10 11// Returns: the product of a + ib and c + id12 13COMPILER_RT_ABI float _Complex14__mulsc3(float __a, float __b, float __c, float __d);15 16enum {zero, non_zero, inf, NaN, non_zero_nan};17 18int19classify(float _Complex x)20{21    if (x == 0)22        return zero;23    if (isinf(crealf(x)) || isinf(cimagf(x)))24        return inf;25    if (isnan(crealf(x)) && isnan(cimagf(x)))26        return NaN;27    if (isnan(crealf(x)))28    {29        if (cimagf(x) == 0)30            return NaN;31        return non_zero_nan;32    }33    if (isnan(cimagf(x)))34    {35        if (crealf(x) == 0)36            return NaN;37        return non_zero_nan;38    }39    return non_zero;40}41 42int test__mulsc3(float a, float b, float c, float d)43{44    float _Complex r = __mulsc3(a, b, c, d);45//     printf("test__mulsc3(%f, %f, %f, %f) = %f + I%f\n",46//             a, b, c, d, crealf(r), cimagf(r));47	float _Complex dividend;48	float _Complex divisor;49	50	__real__ dividend = a;51	__imag__ dividend = b;52	__real__ divisor = c;53	__imag__ divisor = d;54	55    switch (classify(dividend))56    {57    case zero:58        switch (classify(divisor))59        {60        case zero:61            if (classify(r) != zero)62                return 1;63            break;64        case non_zero:65            if (classify(r) != zero)66                return 1;67            break;68        case inf:69            if (classify(r) != NaN)70                return 1;71            break;72        case NaN:73            if (classify(r) != NaN)74                return 1;75            break;76        case non_zero_nan:77            if (classify(r) != NaN)78                return 1;79            break;80        }81        break;82    case non_zero:83        switch (classify(divisor))84        {85        case zero:86            if (classify(r) != zero)87                return 1;88            break;89        case non_zero:90            if (classify(r) != non_zero)91                return 1;92            {93            float _Complex z = a * c - b * d + _Complex_I*(a * d + b * c);94            // relaxed tolerance to arbitrary (1.e-6) amount.95            if (cabsf((r-z)/r) > 1.e-6)96                return 1;97            }98            break;99        case inf:100            if (classify(r) != inf)101                return 1;102            break;103        case NaN:104            if (classify(r) != NaN)105                return 1;106            break;107        case non_zero_nan:108            if (classify(r) != NaN)109                return 1;110            break;111        }112        break;113    case inf:114        switch (classify(divisor))115        {116        case zero:117            if (classify(r) != NaN)118                return 1;119            break;120        case non_zero:121            if (classify(r) != inf)122                return 1;123            break;124        case inf:125            if (classify(r) != inf)126                return 1;127            break;128        case NaN:129            if (classify(r) != NaN)130                return 1;131            break;132        case non_zero_nan:133            if (classify(r) != inf)134                return 1;135            break;136        }137        break;138    case NaN:139        switch (classify(divisor))140        {141        case zero:142            if (classify(r) != NaN)143                return 1;144            break;145        case non_zero:146            if (classify(r) != NaN)147                return 1;148            break;149        case inf:150            if (classify(r) != NaN)151                return 1;152            break;153        case NaN:154            if (classify(r) != NaN)155                return 1;156            break;157        case non_zero_nan:158            if (classify(r) != NaN)159                return 1;160            break;161        }162        break;163    case non_zero_nan:164        switch (classify(divisor))165        {166        case zero:167            if (classify(r) != NaN)168                return 1;169            break;170        case non_zero:171            if (classify(r) != NaN)172                return 1;173            break;174        case inf:175            if (classify(r) != inf)176                return 1;177            break;178        case NaN:179            if (classify(r) != NaN)180                return 1;181            break;182        case non_zero_nan:183            if (classify(r) != NaN)184                return 1;185            break;186        }187        break;188    }189    190    return 0;191}192 193float x[][2] =194{195    { 1.e-6,  1.e-6},196    {-1.e-6,  1.e-6},197    {-1.e-6, -1.e-6},198    { 1.e-6, -1.e-6},199 200    { 1.e+6,  1.e-6},201    {-1.e+6,  1.e-6},202    {-1.e+6, -1.e-6},203    { 1.e+6, -1.e-6},204 205    { 1.e-6,  1.e+6},206    {-1.e-6,  1.e+6},207    {-1.e-6, -1.e+6},208    { 1.e-6, -1.e+6},209 210    { 1.e+6,  1.e+6},211    {-1.e+6,  1.e+6},212    {-1.e+6, -1.e+6},213    { 1.e+6, -1.e+6},214 215    {NAN, NAN},216    {-INFINITY, NAN},217    {-2, NAN},218    {-1, NAN},219    {-0.5, NAN},220    {-0., NAN},221    {+0., NAN},222    {0.5, NAN},223    {1, NAN},224    {2, NAN},225    {INFINITY, NAN},226 227    {NAN, -INFINITY},228    {-INFINITY, -INFINITY},229    {-2, -INFINITY},230    {-1, -INFINITY},231    {-0.5, -INFINITY},232    {-0., -INFINITY},233    {+0., -INFINITY},234    {0.5, -INFINITY},235    {1, -INFINITY},236    {2, -INFINITY},237    {INFINITY, -INFINITY},238 239    {NAN, -2},240    {-INFINITY, -2},241    {-2, -2},242    {-1, -2},243    {-0.5, -2},244    {-0., -2},245    {+0., -2},246    {0.5, -2},247    {1, -2},248    {2, -2},249    {INFINITY, -2},250 251    {NAN, -1},252    {-INFINITY, -1},253    {-2, -1},254    {-1, -1},255    {-0.5, -1},256    {-0., -1},257    {+0., -1},258    {0.5, -1},259    {1, -1},260    {2, -1},261    {INFINITY, -1},262 263    {NAN, -0.5},264    {-INFINITY, -0.5},265    {-2, -0.5},266    {-1, -0.5},267    {-0.5, -0.5},268    {-0., -0.5},269    {+0., -0.5},270    {0.5, -0.5},271    {1, -0.5},272    {2, -0.5},273    {INFINITY, -0.5},274 275    {NAN, -0.},276    {-INFINITY, -0.},277    {-2, -0.},278    {-1, -0.},279    {-0.5, -0.},280    {-0., -0.},281    {+0., -0.},282    {0.5, -0.},283    {1, -0.},284    {2, -0.},285    {INFINITY, -0.},286 287    {NAN, 0.},288    {-INFINITY, 0.},289    {-2, 0.},290    {-1, 0.},291    {-0.5, 0.},292    {-0., 0.},293    {+0., 0.},294    {0.5, 0.},295    {1, 0.},296    {2, 0.},297    {INFINITY, 0.},298 299    {NAN, 0.5},300    {-INFINITY, 0.5},301    {-2, 0.5},302    {-1, 0.5},303    {-0.5, 0.5},304    {-0., 0.5},305    {+0., 0.5},306    {0.5, 0.5},307    {1, 0.5},308    {2, 0.5},309    {INFINITY, 0.5},310 311    {NAN, 1},312    {-INFINITY, 1},313    {-2, 1},314    {-1, 1},315    {-0.5, 1},316    {-0., 1},317    {+0., 1},318    {0.5, 1},319    {1, 1},320    {2, 1},321    {INFINITY, 1},322 323    {NAN, 2},324    {-INFINITY, 2},325    {-2, 2},326    {-1, 2},327    {-0.5, 2},328    {-0., 2},329    {+0., 2},330    {0.5, 2},331    {1, 2},332    {2, 2},333    {INFINITY, 2},334 335    {NAN, INFINITY},336    {-INFINITY, INFINITY},337    {-2, INFINITY},338    {-1, INFINITY},339    {-0.5, INFINITY},340    {-0., INFINITY},341    {+0., INFINITY},342    {0.5, INFINITY},343    {1, INFINITY},344    {2, INFINITY},345    {INFINITY, INFINITY}346 347};348 349int main()350{351    const unsigned N = sizeof(x) / sizeof(x[0]);352    unsigned i, j;353    for (i = 0; i < N; ++i)354    {355        for (j = 0; j < N; ++j)356        {357            if (test__mulsc3(x[i][0], x[i][1], x[j][0], x[j][1]))358                return 1;359        }360    }361 362    return 0;363}364