Implement better hypot function

This commit is contained in:
Justine Tunney 2021-02-21 11:06:18 -08:00
parent 6c7b8facaa
commit 4a5698b5c9
14 changed files with 293 additions and 62 deletions

Binary file not shown.

View file

@ -651,17 +651,17 @@ typedef uint64_t uintmax_t;
#ifndef __STRICT_ANSI__
#if defined(__GNUC__) || defined(__llvm__)
#pragma GCC diagnostic ignored "-Wsign-compare" /* lint needs to change */
#pragma GCC diagnostic ignored "-Wtype-limits" /* makes macros unsafe */
#pragma GCC diagnostic ignored "-Woverflow" /* also breaks macros */
#pragma GCC diagnostic ignored "-Wformat" /* forces only gnu pf */
#pragma GCC diagnostic ignored "-Wunused-parameter" /* extreme prejudice */
#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce! */
#pragma GCC diagnostic ignored "-Wunused-variable" /* belongs in tidy */
#pragma GCC diagnostic ignored "-Wsign-compare" /* lint needs to change */
#pragma GCC diagnostic ignored "-Wtype-limits" /* makes macros unsafe */
#pragma GCC diagnostic ignored "-Woverflow" /* also breaks macros */
#pragma GCC diagnostic ignored "-Wformat" /* forces only gnu pf */
#pragma GCC diagnostic ignored "-Wunused-parameter" /* extreme prejudice */
#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce! */
#pragma GCC diagnostic ignored "-Wunused-variable" /* belongs in tidy */
#pragma GCC diagnostic ignored "-Wformat-extra-args" /* is also broken */
#pragma GCC diagnostic ignored "-Wparentheses" /* annoying tidy */
#pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */
#pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */
#pragma GCC diagnostic ignored "-Wparentheses" /* annoying tidy */
#pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */
#pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wimplicit-int"
#endif /* C++ */
@ -678,7 +678,8 @@ typedef uint64_t uintmax_t;
#endif /* GCC6+ */
#if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif /* GCC8+ */
#pragma GCC diagnostic ignored "-Wstringop-overflow" /* breaks strndup */
#endif /* GCC8+ */
#if __GNUC__ + 0 >= 9
#pragma GCC diagnostic ignored /* "always true" breaks dce */ "-Waddress"
#endif /* GCC9+ */
@ -689,8 +690,8 @@ typedef uint64_t uintmax_t;
"-Wincompatible-pointer-types-discards-qualifiers"
#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
#pragma clang diagnostic ignored "-Wparentheses-equality" /*-save-temps*/
#pragma clang diagnostic ignored "-Wunused-value" /*({-save-temps})*/
#pragma clang diagnostic ignored "-Wstring-plus-int" /* special ed */
#pragma clang diagnostic ignored "-Wunused-value" /*({-save-temps})*/
#pragma clang diagnostic ignored "-Wstring-plus-int" /* special ed */
#pragma clang diagnostic ignored "-Wunused-value" /* extreme prejudice */
#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
#pragma clang diagnostic ignored \

View file

@ -22,8 +22,7 @@ void *reallocarray(void *, size_t, size_t) nodiscard;
void *valloc(size_t) attributeallocsize((1)) vallocesque;
void *pvalloc(size_t) attributeallocsize((1)) mallocesque;
char *strdup(const char *) paramsnonnull() mallocesque;
char *strndup(const char *, size_t) paramsnonnull()
attributeallocsize((2)) mallocesque;
char *strndup(const char *, size_t) paramsnonnull() mallocesque;
int posix_memalign(void **, size_t, size_t); /* wut */
bool __grow(void *, size_t *, size_t, size_t) paramsnonnull((1, 2)) libcesque;

51
libc/str/a64l.c Normal file
View file

@ -0,0 +1,51 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/str/str.h"
static const signed char kBase64i[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, /* 0x20 */
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, /* 0x30 */
-1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, /* 0x40 */
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, -1, -1, -1, /* 0x50 */
-1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, /* 0x60 */
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, /* 0x70 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xF0 */
};
/**
* Converts base64 to 32-bit integer.
*/
long a64l(const char *s) {
uint32_t i, v, x;
for (x = i = 0; i < 6; ++i) {
v = kBase64i[s[i] & 0xff];
if (v == -1) break;
x |= v << (i * 6);
}
return (int32_t)x;
}

33
libc/str/l64a.c Normal file
View file

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/str/str.h"
/**
* Converts 32-bit integer to base64.
*/
char *l64a(long x) {
static char b[7];
uint32_t u, i = 0;
for (u = x; u; u >>= 6) {
b[i++] = ("./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz")[u & 63];
}
b[i] = '\0';
return b;
}

View file

@ -182,6 +182,8 @@ int timingsafe_memcmp(const void *, const void *, size_t);
void *memmem(const void *, size_t, const void *, size_t)
paramsnonnull() nothrow nocallback nosideeffect;
char *strerror(int) returnsnonnull nothrow nocallback;
long a64l(const char *);
char *l64a(long);
char *tinystrstr(const char *, const char *) strlenesque;
char16_t *tinystrstr16(const char16_t *, const char16_t *) strlenesque;

View file

@ -1,7 +1,7 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
@ -16,19 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.h"
.source __FILE__
#include "libc/math.h"
// Returns euclidean distance in 2d space.
hypotl: push %rbp
mov %rsp,%rbp
.profilable
fldt 32(%rbp)
fldt 16(%rbp)
fmul %st,%st
fxch
fmul %st,%st
faddp
pop %rbp
ret
.endfn hypotl,globl
/**
* Returns euclidean distance.
*/
double hypot(double a, double b) {
double r;
if (isinf(a) || isinf(b)) return INFINITY;
if (isunordered(a, b)) return NAN;
if (!a) return 0;
r = b / a;
return fabs(a) * sqrt(1 + r * r);
}

View file

@ -1,7 +1,7 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
@ -16,15 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.h"
.source __FILE__
#include "libc/math.h"
// Returns euclidean distance in 2d space.
hypotf: .leafprologue
.profilable
mulss %xmm1,%xmm1
mulss %xmm0,%xmm0
addss %xmm1,%xmm0
sqrtss %xmm0,%xmm0
.leafepilogue
.endfn hypotf,globl
/**
* Returns euclidean distance.
*/
float hypotf(float a, float b) {
float r;
if (isinf(a) || isinf(b)) return INFINITY;
if (isunordered(a, b)) return NAN;
if (!a) return 0;
r = b / a;
return fabsf(a) * sqrtf(1 + r * r);
}

31
libc/tinymath/hypotl.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/math.h"
/**
* Returns euclidean distance.
*/
long double hypotl(long double a, long double b) {
long double r;
if (isinf(a) || isinf(b)) return INFINITY;
if (isunordered(a, b)) return NAN;
if (!a) return 0;
r = b / a;
return fabsl(a) * sqrtl(1 + r * r);
}

View file

@ -29,6 +29,7 @@ int xwrite(int, const void *, uint64_t);
*/
void xdie(void) wontreturn;
char *xdtoaf(float) _XMAL;
char *xdtoa(long double) _XMAL;
char *xasprintf(const char *, ...) printfesque(1) paramsnonnull((1)) _XMAL;
char *xvasprintf(const char *, va_list) _XPNN _XMAL;

View file

@ -1,5 +1,5 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
@ -16,15 +16,17 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.h"
.source __FILE__
#include "libc/mem/mem.h"
#include "libc/x/x.h"
#include "third_party/gdtoa/gdtoa.h"
// Returns euclidean distance in 2d space.
hypot: .leafprologue
.profilable
mulsd %xmm1,%xmm1
mulsd %xmm0,%xmm0
addsd %xmm1,%xmm0
sqrtsd %xmm0,%xmm0
.leafepilogue
.endfn hypot,globl
/**
* Converts double to string w/ high-accuracy the easy way.
*
* @return string that needs to be free'd
*/
char *xdtoaf(float d) {
char *p = xmalloc(32);
g_ffmt_p(p, &d, 7, 32, 2);
return p;
}

39
test/libc/str/a64l_test.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(l64a, test) {
EXPECT_STREQ("", l64a(0));
EXPECT_STREQ("zzzzz1", l64a(-1));
EXPECT_STREQ("zzzzz/", l64a(0x7fffffff));
}
TEST(a64l, test) {
EXPECT_EQ(0, a64l(""));
EXPECT_EQ(-1, a64l("zzzzz1"));
EXPECT_EQ(0x7fffffff, a64l("zzzzz/"));
}
BENCH(a64l, bench) {
EZBENCH2(
"a64l", donothing,
a64l("./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
}

View file

@ -0,0 +1,75 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/math.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(hypot, test) {
EXPECT_STREQ("0", gc(xdtoa(hypot(0, 0))));
EXPECT_STREQ("5", gc(xdtoa(hypot(3, 4))));
EXPECT_STREQ("5", gc(xdtoa(hypot(-3, -4))));
EXPECT_STREQ("1.414213562373095e+154", gc(xdtoa(hypot(1e154, 1e154))));
EXPECT_STREQ("NAN", gc(xdtoa(hypot(0, NAN))));
EXPECT_STREQ("NAN", gc(xdtoa(hypot(NAN, 0))));
EXPECT_STREQ("NAN", gc(xdtoa(hypot(NAN, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypot(INFINITY, 0))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypot(0, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypot(INFINITY, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypot(NAN, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypot(INFINITY, INFINITY))));
}
TEST(hypotf, test) {
EXPECT_STREQ("0", gc(xdtoa(hypotf(0, 0))));
EXPECT_STREQ("5", gc(xdtoa(hypotf(3, 4))));
EXPECT_STREQ("5", gc(xdtoa(hypotf(-3, -4))));
EXPECT_STREQ("1.414214e+38", gc(xdtoaf(hypotf(1e38, 1e38))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotf(0, NAN))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotf(NAN, 0))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotf(NAN, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotf(INFINITY, 0))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotf(0, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotf(INFINITY, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotf(NAN, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotf(INFINITY, INFINITY))));
}
TEST(hypotl, test) {
EXPECT_STREQ("0", gc(xdtoa(hypotl(0, 0))));
EXPECT_STREQ("5", gc(xdtoa(hypotl(3, 4))));
EXPECT_STREQ("5", gc(xdtoa(hypotl(-3, -4))));
EXPECT_STREQ("1.414213562373095e+4931", gc(xdtoa(hypotl(1e4931L, 1e4931L))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotl(0, NAN))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotl(NAN, 0))));
EXPECT_STREQ("NAN", gc(xdtoa(hypotl(NAN, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotl(INFINITY, 0))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotl(0, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotl(INFINITY, NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotl(NAN, INFINITY))));
EXPECT_STREQ("INFINITY", gc(xdtoa(hypotl(INFINITY, INFINITY))));
}
BENCH(hypot, bench) {
volatile double a = 2;
volatile double b = 3;
EZBENCH2("hypotf", donothing, EXPROPRIATE(hypotf(a, b)));
EZBENCH2("hypot", donothing, EXPROPRIATE(hypot(a, b)));
EZBENCH2("hypotl", donothing, EXPROPRIATE(hypotl(a, b)));
}

View file

@ -126,6 +126,7 @@ const char *const kGccOnlyFlags[] = {
"--noexecstack",
"-Wa,--nocompress-debug-sections",
"-Wa,--noexecstack",
"-Wa,-msse2avx",
"-Wno-unused-but-set-variable",
"-Wunsafe-loop-optimizations",
"-fbranch-target-load-optimize",
@ -386,8 +387,6 @@ int main(int argc, char *argv[]) {
} else if (!strcmp(argv[i], "-msse2avx")) {
if (isgcc) {
AddArg(argv[i]);
} else if (isclang) {
AddArg("-Wa,-msse2avx");
}
} else if (!strcmp(argv[i], "-fsanitize=address")) {
if (isgcc && ccversion >= 6) wantasan = true;