From 37cebaabf65fe3961b9932c6582d15b3b676cefe Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Mon, 17 Jun 2019 09:43:34 +0200 Subject: Perform constant propagation and strength reduction on conditional moves A conditional move whose condition is statically known becomes a regular move. Otherwise, the condition can sometimes be simplified by strength reduction. --- test/regression/ifconv.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'test/regression') diff --git a/test/regression/ifconv.c b/test/regression/ifconv.c index dcbf43e5..e12a394c 100644 --- a/test/regression/ifconv.c +++ b/test/regression/ifconv.c @@ -83,6 +83,26 @@ float sdoz(float x, float y) return x >= y ? x - y : 0.0f; } +/* Examples where constant propagation should take place */ + +int constprop1(int x) +{ + int n = 0; + return n ? x : 42; +} + +int constprop2(int x) +{ + int n = 1; + return n ? x : 42; +} + +int constprop3(int x, int y) +{ + int n = 0; + return x < n ? y - 1 : y + 1; +} + /* Test harness */ #define TESTI(call) printf(#call " = %d\n", call) -- cgit From ed0cfe4b38208f15763f2d1c0372c441a320ea56 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Mon, 17 Jun 2019 14:22:22 +0200 Subject: Extended asm: print register names according to their types When printing an extended asm code fragment, placeholders %n are replaced by register names. Currently we ignore the fact that some assemblers use different register names depending on the width of the data that resides in the register. For example, x86_64 uses %rax for a 64-bit quantity and %eax for a 32-bit quantity, but CompCert always prints %rax in extended asm statements. This is problematic if we want to use 32-bit integer instructions in extended asm, e.g. int x, y; asm("addl %1, %0", "=r"(x), "r"(y)); produces addl %rax, %rdx which is syntactically incorrect. Another example is ARM FP registers: D0 is a double-precision float, but S0 is a single-precision float. This commit partially solves this issue by taking into account the Cminor type of the asm parameter when printing the corresponding register. Continuing the previous example, int x, y; asm("addl %1, %0", "=r"(x), "r"(y)); now produces addl %eax, %edx This is not perfect yet: we use Cminor types, because this is all we have at hand, and not source C types, hence "char" and "short" parameters are still printed like "int" parameters, which is not good for x86. (I.e. we produce %eax where GCC might have produced %al or %ax.) We'll leave this issue open. --- test/regression/extasm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test/regression') diff --git a/test/regression/extasm.c b/test/regression/extasm.c index babc57f1..83a07a05 100644 --- a/test/regression/extasm.c +++ b/test/regression/extasm.c @@ -33,6 +33,7 @@ int main() void * y; long long z; double f; + float sf; char c[16]; /* No inputs, no outputs */ @@ -72,6 +73,15 @@ int main() #ifdef FAILURES asm("FAIL4 a:%[a]" : "=r"(x) : [z]"i"(0)); #endif + /* One argument of each type */ + asm("TEST15 int32 %0" : : "r" (x)); +#ifdef SIXTYFOUR + asm("TEST15 int64 %0" : : "r" (z)); +#else + asm("TEST15 int64 %Q0 / %R0" : : "r" (z)); +#endif + asm("TEST15 float64 %0" : : "r" (f)); + asm("TEST15 float32 %0" : : "r" (sf)); /* Various failures */ #ifdef FAILURES asm("FAIL5 out:%0,%1" : "=r"(x), "=r"(y)); -- cgit From 7cd0af8ba5d737fa9c45bb9fa454b38e9704097a Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Sun, 7 Jul 2019 17:39:54 +0200 Subject: When testing builtin functions, prevent constant propagation Now that some builtin functions have known semantics, constant propagation can happen in this test. This defeats the purpose, which is to check that the correct processor instructions are generated. To prevent this constant propagation, we move the initialized variables to global scope. Since they are not "const", their values are not known to the optimizer. --- test/regression/builtins-arm.c | 11 ++++++----- test/regression/builtins-powerpc.c | 15 ++++++++------- test/regression/builtins-riscV.c | 14 +++++++------- test/regression/builtins-x86.c | 19 ++++++++++--------- 4 files changed, 31 insertions(+), 28 deletions(-) (limited to 'test/regression') diff --git a/test/regression/builtins-arm.c b/test/regression/builtins-arm.c index 709343ce..d06e8e5e 100644 --- a/test/regression/builtins-arm.c +++ b/test/regression/builtins-arm.c @@ -2,14 +2,15 @@ #include +unsigned int x = 0x12345678; +unsigned int y = 0xDEADBEEF; +unsigned long long xx = 0x1234567812345678ULL; +double a = 3.14159; +unsigned short s = 0x1234; + int main(int argc, char ** argv) { - unsigned int x = 0x12345678; - unsigned int y = 0xDEADBEEF; - unsigned long long xx = 0x1234567812345678ULL; unsigned z; - double a = 3.14159; - unsigned short s = 0x1234; printf("bswap(%x) = %x\n", x, __builtin_bswap(x)); printf("bswap16(%x) = %x\n", s, __builtin_bswap16(s)); diff --git a/test/regression/builtins-powerpc.c b/test/regression/builtins-powerpc.c index 23e9d191..8fd5818b 100644 --- a/test/regression/builtins-powerpc.c +++ b/test/regression/builtins-powerpc.c @@ -9,16 +9,17 @@ char * check_relative_error(double exact, double actual, double precision) return fabs(relative_error) <= precision ? "OK" : "ERROR"; } +unsigned int x = 0x12345678; +unsigned int y = 0xDEADBEEF; +unsigned long long xx = 0x1234567812345678ULL; +double a = 3.14159; +double b = 2.718; +double c = 1.414; +unsigned short s = 0x1234; + int main(int argc, char ** argv) { - unsigned int x = 0x12345678; - unsigned int y = 0xDEADBEEF; - unsigned long long xx = 0x1234567812345678ULL; unsigned z; - double a = 3.14159; - double b = 2.718; - double c = 1.414; - unsigned short s = 0x1234; printf("mulhw(%x, %x) = %x\n", x, y, __builtin_mulhw(x, y)); printf("mulhwu(%x, %x) = %x\n", x, y, __builtin_mulhwu(x, y)); diff --git a/test/regression/builtins-riscV.c b/test/regression/builtins-riscV.c index a302a6c4..c34fdf2c 100644 --- a/test/regression/builtins-riscV.c +++ b/test/regression/builtins-riscV.c @@ -2,15 +2,15 @@ #include +unsigned int x = 0x12345678; +unsigned short s = 0x1234; +unsigned long long zz = 0x123456789ABCDEF0ULL; +double a = 3.14159; +double b = 2.718; +double c = 1.414; + int main(int argc, char ** argv) { - unsigned int x = 0x12345678; - unsigned short s = 0x1234; - unsigned long long zz = 0x123456789ABCDEF0ULL; - double a = 3.14159; - double b = 2.718; - double c = 1.414; - printf("bswap16(%x) = %x\n", s, __builtin_bswap16(s)); printf("bswap32(%x) = %x\n", x, __builtin_bswap32(x)); printf("bswap64(%llx) = %llx\n", zz, __builtin_bswap64(zz)); diff --git a/test/regression/builtins-x86.c b/test/regression/builtins-x86.c index 1ba213e7..6233f9fd 100644 --- a/test/regression/builtins-x86.c +++ b/test/regression/builtins-x86.c @@ -2,18 +2,19 @@ #include +unsigned int x = 0x12345678; +unsigned int y = 0xDEADBEEF; +unsigned long long xx = 0x1234567812345678ULL; +unsigned long long yy = 0x1234567800000000ULL; +unsigned long long zz = 0x123456789ABCDEF0ULL; +double a = 3.14159; +double b = 2.718; +double c = 1.414; +unsigned short s = 0x1234; + int main(int argc, char ** argv) { - unsigned int x = 0x12345678; - unsigned int y = 0xDEADBEEF; - unsigned long long xx = 0x1234567812345678ULL; - unsigned long long yy = 0x1234567800000000ULL; - unsigned long long zz = 0x123456789ABCDEF0ULL; unsigned z; - double a = 3.14159; - double b = 2.718; - double c = 1.414; - unsigned short s = 0x1234; printf("bswap(%x) = %x\n", x, __builtin_bswap(x)); printf("bswap16(%x) = %x\n", s, __builtin_bswap16(s)); -- cgit