Enhance chibicc

This commit is contained in:
Justine Tunney 2020-12-09 04:00:48 -08:00
parent 8da931a7f6
commit 9df2cef4c4
52 changed files with 2606 additions and 2004 deletions

View file

@ -11,7 +11,7 @@ int main() {
char *p2 = alloca(16);
char *p3 = 1 + (char *)alloca(3) + 1;
p3 -= 2;
char *p4 = fn(1, alloca(16), 3);
char *p4 = fn(1, __builtin_alloca(16), 3);
ASSERT(16, p1 - p2);
ASSERT(16, p2 - p3);

View file

@ -128,5 +128,11 @@ int main() {
ASSERT(9, v1[6]);
ASSERT(10, v1[7]);
{
char *p;
asm("mov\t%1,%0" : "=r"(p) : "r"("hello"));
ASSERT(1, !strcmp(p, "hello"));
}
return 0;
}

View file

@ -0,0 +1,8 @@
#include "third_party/chibicc/test/test.h"
_Static_assert(1);
_Static_assert(1, "hey");
main() {
_Static_assert(sizeof(int) == 4, "wut");
}

View file

@ -1,6 +1,21 @@
#include "third_party/chibicc/test/test.h"
void doge() __attribute__((__nonnull__));
void cate(char *) __attribute__((__nonnull__(1)));
int var __attribute__((__section__(".data.var")));
int ar[4] __attribute__((__section__(".data.var")));
typedef int int2[2] __attribute__((__aligned__(64)));
typedef int int4[4] __attribute__((__warn_if_not_aligned__(16)));
__attribute__((__nonnull__)) void doge2();
__attribute__((__nonnull__(1))) void cate2(char *);
__attribute__((__section__(".data.var"))) int var2;
__attribute__((__section__(".data.var"))) int ar2[4];
int main() {
int2 a;
ASSERT(64, _Alignof(int2));
ASSERT(64, _Alignof(a));
ASSERT(5, ({
struct {
char a;

View file

@ -8,10 +8,87 @@
#define FPCLASSIFY(x) \
__builtin_fpclassify(FPNAN, FPINFINITE, FPNORMAL, FPSUBNORMAL, FPZERO, x)
#define conceal(x) \
({ \
typeof(x) cloak = x; \
asm("" : "+r"(cloak)); \
cloak; \
})
struct frame {
struct frame *next;
intptr_t addr;
};
struct frame *frame(void) {
struct frame *myframe = __builtin_frame_address(0);
struct frame *parentframe = myframe->next;
return parentframe;
}
void test_frame_address(void) {
ASSERT(1, __builtin_frame_address(0) == frame());
}
void test_constant(void) {
ASSERT(1, __builtin_constant_p(1));
ASSERT(0, __builtin_constant_p(conceal(1)));
ASSERT(0, __builtin_constant_p(stdin));
ASSERT(1, __builtin_constant_p(__builtin_popcount(0b10111011)));
ASSERT(1, __builtin_constant_p(__builtin_popcountll((size_t)0b10111011)));
}
void test_ignored(void) {
ASSERT(123, __builtin_assume_aligned(123, 8));
ASSERT(123, __builtin_assume_aligned(123, 32, 8));
ASSERT(123, __builtin_expect(123, 0));
}
void __attribute__((__aligned__(16))) test_clz(void) {
ASSERT(31, __builtin_clz(1));
ASSERT(63, __builtin_clzl(1));
ASSERT(63, __builtin_clzll(1));
ASSERT(25, __builtin_clz(77));
ASSERT(4, __builtin_clz(0x08000000));
ASSERT(4, __builtin_clz(0xfff08000000));
ASSERT(25, __builtin_clz(conceal(77)));
__builtin_clz(conceal(77));
}
__attribute__((__weak__)) void test_ctz(void) {
ASSERT(0, __builtin_ctz(1));
ASSERT(0, __builtin_ctz(77));
ASSERT(27, __builtin_ctz(0x08000000));
ASSERT(27, __builtin_ctz(0xffff08000000));
ASSERT(63, __builtin_ctzl(0x8000000000000000));
ASSERT(63, __builtin_ctzll(0x8000000000000000));
ASSERT(0, __builtin_ctz(conceal(77)));
}
void test_ffs(void) {
ASSERT(0, __builtin_ffs(0));
ASSERT(1, __builtin_ffs(1));
ASSERT(1, __builtin_ffs(77));
ASSERT(28, __builtin_ffs(0x08000000));
ASSERT(28, __builtin_ffs(0xffff08000000));
ASSERT(1, __builtin_ffs(conceal(77)));
}
void test_popcnt(void) {
ASSERT(0, __builtin_popcount(0));
ASSERT(1, __builtin_popcount(1));
ASSERT(6, __builtin_popcount(0b10111011));
ASSERT(6, __builtin_popcountl(0b10111011));
ASSERT(6, __builtin_popcountll(0xbb00000000000000));
ASSERT(6, __builtin_popcountl(conceal(0b10111011)));
}
void test_bswap(void) {
ASSERT(0x3412, __builtin_bswap16(0x1234));
ASSERT(0x78563412, __builtin_bswap32(0x12345678));
ASSERT(0xefcdab8967452301, __builtin_bswap64(0x0123456789abcdef));
ASSERT(0xefcdab89, __builtin_bswap32(0x0123456789abcdef));
ASSERT(0x78563412, __builtin_bswap32(conceal(0x12345678)));
}
void test_fpclassify(void) {
@ -38,48 +115,34 @@ void test_fpclassify(void) {
ASSERT(FPNAN, FPCLASSIFY(__builtin_nanl("")));
}
void __attribute__((__aligned__(16))) test_clz(void) {
ASSERT(31, __builtin_clz(1));
ASSERT(63, __builtin_clzl(1));
ASSERT(63, __builtin_clzll(1));
ASSERT(25, __builtin_clz(77));
ASSERT(4, __builtin_clz(0x08000000));
ASSERT(4, __builtin_clz(0xfff08000000));
void test_strlen(void) {
ASSERT(5, strlen("hello"));
ASSERT(5, __builtin_strlen("hello"));
}
__attribute__((__weak__)) void test_ctz(void) {
ASSERT(0, __builtin_ctz(1));
ASSERT(0, __builtin_ctz(77));
ASSERT(27, __builtin_ctz(0x08000000));
ASSERT(27, __builtin_ctz(0xffff08000000));
ASSERT(63, __builtin_ctzl(0x8000000000000000));
ASSERT(63, __builtin_ctzll(0x8000000000000000));
void test_strchr(void) {
ASSERT(1, __builtin_strchr("hello", 'z') == NULL);
ASSERT(0, (strcmp)(__builtin_strchr("hello", 'e'), "ello"));
}
void test_ffs(void) {
ASSERT(0, __builtin_ffs(0));
ASSERT(1, __builtin_ffs(1));
ASSERT(1, __builtin_ffs(77));
ASSERT(28, __builtin_ffs(0x08000000));
ASSERT(28, __builtin_ffs(0xffff08000000));
void test_strpbrk(void) {
ASSERT(1, __builtin_strpbrk("hello", "z") == NULL);
ASSERT(0, (strcmp)(__builtin_strpbrk("hello", "ze"), "ello"));
}
void test_popcnt(void) {
ASSERT(0, __builtin_popcount(0));
ASSERT(1, __builtin_popcount(1));
ASSERT(6, __builtin_popcount(0b10111011));
ASSERT(6, __builtin_popcountl(0b10111011));
ASSERT(6, __builtin_popcountll(0xbb00000000000000));
}
void test_bswap(void) {
ASSERT(0x3412, __builtin_bswap16(0x1234));
ASSERT(0x78563412, __builtin_bswap32(0x12345678));
ASSERT(0xefcdab8967452301, __builtin_bswap64(0x0123456789abcdef));
ASSERT(0xefcdab89, __builtin_bswap32(0x0123456789abcdef));
void test_strstr(void) {
ASSERT(1, __builtin_strstr("hello", "sup") == NULL);
ASSERT(0, (strcmp)(__builtin_strstr("hello", "ell"), "ello"));
}
void test_memcpy(void) {
{
char x[5] = {4, 3, 2, 1, 0};
char y[5] = {0, 1, 2, 3, 4};
char z[5] = {2, 3, 4, 1, 0};
ASSERT(1, x == (memcpy)(x, y + 2, 3));
ASSERT(0, memcmp(x, z, 5));
}
{
char x[5] = {4, 3, 2, 1, 0};
char y[5] = {0, 1, 2, 3, 4};
@ -95,6 +158,109 @@ void test_memcpy(void) {
ASSERT(1, x == __builtin_memcpy(x, y + 2, n));
ASSERT(0, memcmp(x, z, 5));
}
{
char x[5] = {4, 3, 2, 1, 0};
ASSERT(1, x == __builtin_memcpy(x, x + 1, 4));
ASSERT(0, memcmp(x, (char[5]){3, 2, 1, 0, 0}, 5));
}
}
void test_add_overflow(void) {
{
int z;
ASSERT(0, __builtin_add_overflow(2, 3, &z));
ASSERT(5, z);
}
{
int x, y, z;
x = 2;
y = 3;
ASSERT(0, __builtin_add_overflow(x, y, &z));
ASSERT(5, z);
}
{
int x, y, z;
x = 0x7fffffff;
y = 1;
ASSERT(1, __builtin_add_overflow(x, y, &z));
ASSERT(-2147483648, z);
}
{
long x, y, z;
x = 0x7fffffff;
y = 1;
ASSERT(0, __builtin_add_overflow(x, y, &z));
ASSERT(2147483648, z);
}
}
void test_sub_overflow(void) {
{
int x, y, z;
x = 2;
y = 3;
ASSERT(0, __builtin_sub_overflow(x, y, &z));
ASSERT(-1, z);
}
{
int x, y, z;
x = -2147483648;
y = 1;
ASSERT(1, __builtin_sub_overflow(x, y, &z));
ASSERT(2147483647, z);
}
{
long x, y, z;
x = -2147483648;
y = 1;
ASSERT(0, __builtin_sub_overflow(x, y, &z));
ASSERT(-2147483649, z);
}
}
void test_mul_overflow(void) {
{
int x, y, z;
x = 2;
y = 3;
ASSERT(0, __builtin_mul_overflow(x, y, &z));
ASSERT(6, z);
}
{
int x, y, z;
x = 2147483647;
y = 2;
ASSERT(1, __builtin_mul_overflow(x, y, &z));
ASSERT(-2, z);
}
{
long x, y, z;
x = 2147483647;
y = 2;
ASSERT(0, __builtin_mul_overflow(x, y, &z));
ASSERT(4294967294, z);
}
}
void test_neg_overflow(void) {
{
int x, z;
x = 2;
ASSERT(0, __builtin_neg_overflow(x, &z));
ASSERT(-2, z);
}
{
int x, z;
x = -2147483648;
ASSERT(1, __builtin_neg_overflow(x, &z));
ASSERT(-2147483648, z);
}
{
long x, z;
x = -2147483648;
ASSERT(0, __builtin_neg_overflow(x, &z));
ASSERT(2147483648, z);
}
}
void test_inf(void) {
@ -225,6 +391,7 @@ void test_offsetof(void) {
int main() {
test_constant();
test_frame_address();
test_types_compatible_p();
test_clz();
test_ctz();
@ -238,5 +405,14 @@ int main() {
test_signbit();
test_memcpy();
test_offsetof();
test_ignored();
test_add_overflow();
test_sub_overflow();
test_mul_overflow();
test_neg_overflow();
test_strlen();
test_strchr();
test_strpbrk();
test_strstr();
return 0;
}

View file

@ -176,6 +176,4 @@ int main() {
ASSERT(1, g40 == 1.5);
ASSERT(1, g41 == 11);
return 0;
}

42
third_party/chibicc/test/dce_test.c vendored Normal file
View file

@ -0,0 +1,42 @@
#include "third_party/chibicc/test/test.h"
int x;
int main(void) {
if (0) {
asm(".error \"the assembler shall fail\"");
}
x = 1 ? 777 : ({
asm(".error \"the system is down\"");
666;
});
ASSERT(777, x);
x = 0;
x = 777 ?: ({
asm(".error \"the system is down\"");
666;
});
x = 0;
x = __builtin_popcount(strlen("hihi")) == 1 ? 777 : ({
asm(".error \"the system is down\"");
666;
});
ASSERT(777, x);
x = 0;
x = strpbrk("hihi", "ei") ? 777 : ({
asm(".error \"the system is down!\"");
666;
});
ASSERT(777, x);
x = 0;
x = !__builtin_strpbrk("HELLO\n", "bxdinupo") ? 777 : ({
asm(".error \"the system is down\"");
666;
});
ASSERT(777, x);
}

View file

@ -87,26 +87,8 @@ unsigned short ushort_fn();
char schar_fn();
short sshort_fn();
int add_all(int n, ...);
typedef struct {
int gp_offset;
int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} __va_elem;
typedef __va_elem va_list[1];
int add_all(int n, ...);
int sprintf(char *buf, char *fmt, ...);
int vsprintf(char *buf, char *fmt, va_list ap);
char *fmt(char *buf, char *fmt, ...) {
va_list ap;
*ap = *(__va_elem *)__va_area__;
vsprintf(buf, fmt, ap);
}
int add_all(int, ...);
int add_all(int, ...);
double add_double(double x, double y);
float add_float(float x, float y);
@ -307,7 +289,7 @@ int main() {
{
char buf[100];
fmt(buf, "%d %d %s", 1, 2, "foo");
sprintf(buf, "%d %d %s", 1, 2, "foo");
fprintf(f, "%s\n", buf);
}
@ -319,7 +301,7 @@ int main() {
ASSERT(0, ({
char buf[100];
fmt(buf, "%d %d %s", 1, 2, "foo");
sprintf(buf, "%d %d %s", 1, 2, "foo");
strcmp("1 2 foo", buf);
}));
@ -342,7 +324,7 @@ int main() {
ASSERT(0, ({
char buf[100];
fmt(buf, "%.1f", (float)3.5);
sprintf(buf, "%.1f", (float)3.5);
strcmp(buf, "3.5");
}));

4
third_party/chibicc/test/hog_test.c vendored Normal file
View file

@ -0,0 +1,4 @@
main(void) {
void *p;
p = "hello";
}

View file

@ -33,7 +33,17 @@ __int128 sub128x5(__int128 a, __int128 b, __int128 c, __int128 d, __int128 e) {
return a - b - c - d - e;
}
__int128 sub128x6(int f, __int128 a, __int128 b, __int128 c, __int128 d,
__int128 e) {
return f - a - b - c - d - e;
}
void lotsOfArgs(const char *file, int line, const char *func, intmax_t beg,
intmax_t end, intmax_t got, const char *gotcode, bool isfatal) {
}
void testLang128(void) {
lotsOfArgs(__FILE__, __LINE__, __FUNCTION__, 0, 0, 0, "", false);
ASSERT(16, sizeof(__int128));
ASSERT(16, sizeof(unsigned __int128));
ASSERT(16, _Alignof(__int128));
@ -64,6 +74,12 @@ void testLang128(void) {
I128(0x19a0da005190a5ac, 0x755fa06484419e38),
I128(0xafc6e44400b9eadd, 0x05e5afdb2e66cdb8),
I128(0x5380c8796909a165, 0x47657977e6c4f381)));
ASSERT128(I128(0x1f1b109234418f84, 0x21f9f24c8535e4f0),
sub128x6(0x5ab6ba38, I128(0x0db9cd085ab6ba38, 0xdaf9c05f15896b5f),
I128(0xb6429ba7b5b38454, 0x4061839d268a0a78),
I128(0x19a0da005190a5ac, 0x755fa06484419e38),
I128(0xafc6e44400b9eadd, 0x05e5afdb2e66cdb8),
I128(0x5380c8796909a165, 0x47657977e6c4f381)));
}
void testCompare128(void) {
@ -8157,6 +8173,27 @@ void testNot128(void) {
ASSERT128(I128(0, 0), ~x);
}
void testAbi(void) {
ASSERT(0, ({
char buf[200];
sprintf(buf, "%d %d %d %d %032jx %032jx", 1, 2, 3, 4,
I128(0x1ffffffff, 0x2ffffffff),
I128(0x3eeeeeeee, 0x4eeeeeeee));
strcmp("1 2 3 4 00000001ffffffff00000002ffffffff "
"00000003eeeeeeee00000004eeeeeeee",
buf);
}));
ASSERT(0, ({
char buf[200];
sprintf(buf, "%d %d %d %d %d %032jx %032jx", 1, 2, 3, 4, 5,
I128(0x1ffffffff, 0x2ffffffff),
I128(0x3eeeeeeee, 0x4eeeeeeee));
strcmp("1 2 3 4 5 00000001ffffffff00000002ffffffff "
"00000003eeeeeeee00000004eeeeeeee",
buf);
}));
}
int main(void) {
testLang128();
testCompare128();
@ -8179,5 +8216,6 @@ int main(void) {
testCastDblUint128();
testCastLdblInt128();
testCastLdblUint128();
testAbi();
return 0;
}

View file

@ -1,6 +1,9 @@
#include "third_party/chibicc/test/test.h"
int main() {
typeof("str") StringInitParen1 = ("str");
char StringInitParen2[] = ("str");
ASSERT(0, ""[0]);
ASSERT(1, sizeof(""));

View file

@ -49,6 +49,8 @@ THIRD_PARTY_CHIBICC_TEST_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_UNICODE \
LIBC_MEM \
LIBC_X \
THIRD_PARTY_CHIBICC \
THIRD_PARTY_COMPILER_RT
THIRD_PARTY_CHIBICC_TEST_DEPS := \
@ -95,6 +97,4 @@ o/$(MODE)/third_party/chibicc/test/%2.com.dbg: \
.PHONY: o/$(MODE)/third_party/chibicc/test
o/$(MODE)/third_party/chibicc/test: \
$(THIRD_PARTY_CHIBICC_TEST_BINS) \
$(THIRD_PARTY_CHIBICC_TEST_CHECKS) \
$(THIRD_PARTY_CHIBICC_TEST_SRCS:%.c=o/$(MODE)/%.chibicc.s) \
$(THIRD_PARTY_CHIBICC_TEST_SRCS:%.c=o/$(MODE)/%.chibicc2.s)
$(THIRD_PARTY_CHIBICC_TEST_CHECKS)

View file

@ -24,6 +24,12 @@ int main() {
sizeof(x);
}));
ASSERT(12, sizeof(typeof(struct { int a, b, c; })));
return 0;
ASSERT(3, ({
label:
3;
}));
ASSERT(3, ({
__typeof(int) x = 3;
x;
}));
}