| /* |
| REQUIRED_ARGS: -mcpu=native |
| PERMUTE_ARGS: -O -inline -release |
| */ |
| |
| import core.stdc.stdio; |
| |
| template tuple(A...) { alias tuple = A; } |
| |
| /////////////////////// |
| |
| // https://github.com/dlang/dmd/pull/11441 |
| |
| long sdiv1(long l) |
| { |
| return l / 2; |
| } |
| |
| int sdiv2(int i) |
| { |
| return i / 2; |
| } |
| |
| void testsdiv2() |
| { |
| assert(sdiv1(10) == 5); |
| assert(sdiv1(-10) == -5); |
| assert(sdiv2(10) == 5); |
| assert(sdiv2(-10) == -5); |
| } |
| |
| /////////////////////// |
| |
| void testulldiv() |
| { |
| __gshared ulong[4][] vectors = |
| [ |
| [10,3,3,1], |
| [10,1,10,0], |
| [3,10,0,3], |
| [10,10,1,0], |
| [10_000_000_000L, 11_000_000_000L, 0, 10_000_000_000L], |
| [11_000_000_000L, 10_000_000_000L, 1, 1_000_000_000L], |
| [11_000_000_000L, 11_000_000_000L, 1, 0], |
| [10_000_000_000L, 10, 1_000_000_000L, 0], |
| [0x8000_0000_0000_0000, 0x8000_0000_0000_0000, 1, 0], |
| [0x8000_0000_0000_0001, 0x8000_0000_0000_0001, 1, 0], |
| [0x8000_0001_0000_0000, 0x8000_0001_0000_0000, 1, 0], |
| [0x8000_0001_0000_0000, 0x8000_0000_0000_0000, 1, 0x1_0000_0000], |
| [0x8000_0001_0000_0000, 0x8000_0000_8000_0000, 1, 0x8000_0000], |
| [0x8000_0000_0000_0000, 0x7FFF_FFFF_FFFF_FFFF, 1, 1], |
| [0x8000_0000_0000_0000, 0x8000_0000_0000_0001, 0, 0x8000_0000_0000_0000], |
| [0x8000_0000_0000_0000, 0x8000_0001_0000_0000, 0, 0x8000_0000_0000_0000], |
| ]; |
| |
| for (size_t i = 0; i < vectors.length; i++) |
| { |
| ulong q = vectors[i][0] / vectors[i][1]; |
| if (q != vectors[i][2]) |
| printf("[%zd] %lld / %lld = %lld, should be %lld\n", |
| i, vectors[i][0], vectors[i][1], q, vectors[i][2]); |
| |
| ulong r = vectors[i][0] % vectors[i][1]; |
| if (r != vectors[i][3]) |
| printf("[%zd] %lld %% %lld = %lld, should be %lld\n", |
| i, vectors[i][0], vectors[i][1], r, vectors[i][3]); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| uint udiv10(uint x) |
| { |
| return x / 10; |
| } |
| |
| uint udiv14(uint x) |
| { |
| return x / 14; |
| } |
| |
| uint udiv14007(uint x) |
| { |
| return x / 14007; |
| } |
| |
| uint umod10(uint x) |
| { |
| return x % 10; |
| } |
| |
| uint umod14(uint x) |
| { |
| return x % 14; |
| } |
| |
| uint umod14007(uint x) |
| { |
| return x % 14007; |
| } |
| |
| uint uremquo10(uint x) |
| { |
| return (x / 10) | (x % 10); |
| } |
| |
| uint uremquo14(uint x) |
| { |
| return (x / 14) | (x % 14); |
| } |
| |
| uint uremquo14007(uint x) |
| { |
| return (x / 14007) | (x % 14007); |
| } |
| |
| |
| |
| ulong uldiv10(ulong x) |
| { |
| return x / 10; |
| } |
| |
| ulong uldiv14(ulong x) |
| { |
| return x / 14; |
| } |
| |
| ulong uldiv14007(ulong x) |
| { |
| return x / 14007; |
| } |
| |
| ulong ulmod10(ulong x) |
| { |
| return x % 10; |
| } |
| |
| ulong ulmod14(ulong x) |
| { |
| return x % 14; |
| } |
| |
| ulong ulmod14007(ulong x) |
| { |
| return x % 14007; |
| } |
| |
| ulong ulremquo10(ulong x) |
| { |
| return (x / 10) | (x % 10); |
| } |
| |
| ulong ulremquo14(ulong x) |
| { |
| return (x / 14) | (x % 14); |
| } |
| |
| ulong ulremquo14007(ulong x) |
| { |
| return (x / 14007) | (x % 14007); |
| } |
| |
| |
| void testfastudiv() |
| { |
| { |
| static uint x10 = 10; |
| static uint x14 = 14; |
| static uint x14007 = 14007; |
| |
| uint u = 10000; |
| uint r; |
| r = udiv10(u); assert(r == u/x10); |
| r = udiv14(u); assert(r == u/x14); |
| r = udiv14007(u); assert(r == u/x14007); |
| r = umod10(u); assert(r == u%x10); |
| r = umod14(u); assert(r == u%x14); |
| r = umod14007(u); assert(r == u%x14007); |
| r = uremquo10(u); assert(r == ((u/10)|(u%x10))); |
| r = uremquo14(u); assert(r == ((u/14)|(u%x14))); |
| r = uremquo14007(u); assert(r == ((u/14007)|(u%x14007))); |
| } |
| { |
| static ulong y10 = 10; |
| static ulong y14 = 14; |
| static ulong y14007 = 14007; |
| |
| ulong u = 10000; |
| ulong r; |
| r = uldiv10(u); assert(r == u/y10); |
| r = uldiv14(u); assert(r == u/y14); |
| r = uldiv14007(u); assert(r == u/y14007); |
| r = ulmod10(u); assert(r == u%y10); |
| r = ulmod14(u); assert(r == u%y14); |
| r = ulmod14007(u); assert(r == u%y14007); |
| r = ulremquo10(u); assert(r == ((u/10)|(u%y10))); |
| r = ulremquo14(u); assert(r == ((u/14)|(u%y14))); |
| r = ulremquo14007(u); assert(r == ((u/14007)|(u%y14007))); |
| } |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=14936 |
| |
| long sldiv1 (long x) { return x / (1L << 1); } |
| long sldiv2 (long x) { return x / (1L << 2); } |
| long sldiv3 (long x) { return x / (1L << 3); } |
| long sldiv7 (long x) { return x / (1L << 7); } |
| long sldiv8 (long x) { return x / (1L << 8); } |
| long sldiv9 (long x) { return x / (1L << 9); } |
| long sldiv30(long x) { return x / (1L << 30); } |
| long sldiv31(long x) { return x / (1L << 31); } |
| long sldiv32(long x) { return x / (1L << 32); } |
| long sldiv33(long x) { return x / (1L << 33); } |
| long sldiv34(long x) { return x / (1L << 34); } |
| long sldiv62(long x) { return x / (1L << 62); } |
| long sldiv63(long x) { return x / (1L << 63); } |
| |
| void testsldiv() |
| { |
| /* Test special div code for signed long divide |
| * by power of 2 for 32 bit targets. |
| */ |
| |
| // printf("63 = %llx\n", sldiv63(-0x7FFF_F8FF_FF3F_2FFFL)); |
| |
| static foreach (C; tuple!( |
| 1,2,3,10,300,1000, |
| 4_1001_2030_0030, |
| 0x7FFF_F8FF_FF3F_2FFFL)) |
| { |
| /* Check if runtime computation matches compile time |
| */ |
| assert(sldiv1 ( C) == C / (1L << 1)); |
| assert(sldiv1 (-C) == -C / (1L << 1)); |
| assert(sldiv2 ( C) == C / (1L << 2)); |
| assert(sldiv2 (-C) == -C / (1L << 2)); |
| assert(sldiv3 ( C) == C / (1L << 3)); |
| assert(sldiv3 (-C) == -C / (1L << 3)); |
| assert(sldiv7 ( C) == C / (1L << 7)); |
| assert(sldiv7 (-C) == -C / (1L << 7)); |
| assert(sldiv8 ( C) == C / (1L << 8)); |
| assert(sldiv8 (-C) == -C / (1L << 8)); |
| assert(sldiv9 ( C) == C / (1L << 9)); |
| assert(sldiv9 (-C) == -C / (1L << 9)); |
| |
| assert(sldiv30( C) == C / (1L << 30)); |
| assert(sldiv30(-C) == -C / (1L << 30)); |
| assert(sldiv31( C) == C / (1L << 31)); |
| assert(sldiv31(-C) == -C / (1L << 31)); |
| assert(sldiv32( C) == C / (1L << 32)); |
| assert(sldiv32(-C) == -C / (1L << 32)); |
| assert(sldiv33( C) == C / (1L << 33)); |
| assert(sldiv33(-C) == -C / (1L << 33)); |
| assert(sldiv34( C) == C / (1L << 34)); |
| assert(sldiv34(-C) == -C / (1L << 34)); |
| assert(sldiv62( C) == C / (1L << 62)); |
| assert(sldiv62(-C) == -C / (1L << 62)); |
| assert(sldiv63( C) == C / (1L << 63)); |
| assert(sldiv63(-C) == -C / (1L << 63)); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=14936 |
| |
| long slmod1 (long x) { return x % (1L << 1); } |
| long slmod2 (long x) { return x % (1L << 2); } |
| long slmod3 (long x) { return x % (1L << 3); } |
| long slmod7 (long x) { return x % (1L << 7); } |
| long slmod8 (long x) { return x % (1L << 8); } |
| long slmod9 (long x) { return x % (1L << 9); } |
| long slmod30(long x) { return x % (1L << 30); } |
| long slmod31(long x) { return x % (1L << 31); } |
| long slmod32(long x) { return x % (1L << 32); } |
| long slmod33(long x) { return x % (1L << 33); } |
| long slmod34(long x) { return x % (1L << 34); } |
| long slmod62(long x) { return x % (1L << 62); } |
| long slmod63(long x) { return x % (1L << 63); } |
| |
| void testslmod() |
| { |
| static foreach (C; tuple!( |
| 1,2,3,10,300,1000, |
| 4_1001_2030_0030, |
| 0x7FFF_F8FF_FF3F_2FFFL)) |
| { |
| /* Check if runtime computation matches compile time |
| */ |
| assert(slmod1 ( C) == C % (1L << 1)); |
| assert(slmod1 (-C) == -C % (1L << 1)); |
| assert(slmod2 ( C) == C % (1L << 2)); |
| assert(slmod2 (-C) == -C % (1L << 2)); |
| assert(slmod3 ( C) == C % (1L << 3)); |
| assert(slmod3 (-C) == -C % (1L << 3)); |
| assert(slmod7 ( C) == C % (1L << 7)); |
| assert(slmod7 (-C) == -C % (1L << 7)); |
| assert(slmod8 ( C) == C % (1L << 8)); |
| assert(slmod8 (-C) == -C % (1L << 8)); |
| assert(slmod9 ( C) == C % (1L << 9)); |
| assert(slmod9 (-C) == -C % (1L << 9)); |
| |
| assert(slmod30( C) == C % (1L << 30)); |
| assert(slmod30(-C) == -C % (1L << 30)); |
| assert(slmod31( C) == C % (1L << 31)); |
| assert(slmod31(-C) == -C % (1L << 31)); |
| assert(slmod32( C) == C % (1L << 32)); |
| assert(slmod32(-C) == -C % (1L << 32)); |
| assert(slmod33( C) == C % (1L << 33)); |
| assert(slmod33(-C) == -C % (1L << 33)); |
| assert(slmod34( C) == C % (1L << 34)); |
| assert(slmod34(-C) == -C % (1L << 34)); |
| assert(slmod62( C) == C % (1L << 62)); |
| assert(slmod62(-C) == -C % (1L << 62)); |
| assert(slmod63( C) == C % (1L << 63)); |
| assert(slmod63(-C) == -C % (1L << 63)); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| T divC(int C, T)(T x) |
| { |
| T y = x; |
| y /= C; |
| assert(y == x / C); |
| y = x; |
| y /= -C; |
| assert(y == x / -C); |
| return x / C; |
| } |
| |
| T modC(int C, T)(T x) |
| { |
| T y = x; |
| y %= C; |
| assert(y == x % C); |
| y = x; |
| y %= -C; |
| assert(y == x % -C); |
| return x % C; |
| } |
| |
| T remquoC(int C, T)(T x) |
| { |
| return (x / C) | (x % C); |
| } |
| |
| void testfastdiv() |
| { |
| static int z = 0; // prevent constant folding by optimizer |
| |
| static foreach (T; tuple!(int, long, uint, ulong)) |
| {{ |
| T u = 10000; |
| T r; |
| static foreach (C; tuple!(10, 14, 14007, -10, -14, -14007)) |
| { |
| r = divC!C(u); assert(r == u / (z + C)); |
| r = modC!C(u); assert(r == u % (z + C)); |
| r = remquoC!C(u); assert(r == ((u / (z + C) | (u % (z + C))))); |
| } |
| }} |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| /* Test the pattern: |
| * replace ((i / C1) / C2) with (i / (C1 * C2)) |
| * when e1 is 0 or 1 and (i2-i1) is a power of 2. |
| */ |
| |
| void divdiv(T, T C1, T C2)(T i) |
| { |
| auto a = (i / C1) / C2; |
| auto b = i / (C1 * C2); |
| if (a != b) assert(0); |
| } |
| |
| void testdivdiv() |
| { |
| divdiv!(int,10,20)(30); |
| divdiv!(uint,10,20)(30); |
| divdiv!(long,10,20)(30); |
| divdiv!(ulong,10,20)(30); |
| |
| divdiv!(int,-10,20)(30); |
| divdiv!(long,-10,20)(30); |
| |
| divdiv!(int,-10,-20)(-30); |
| divdiv!(long,-10,-20)(-30); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void testdivcmp() |
| { |
| // https://github.com/dlang/dmd/pull/7128 |
| static bool foo(uint a, uint b) |
| { |
| return cast(bool)(a / b); // convert / to >= |
| } |
| |
| assert(!foo(3, 4)); |
| assert(foo(4, 4)); |
| assert(foo(5, 4)); |
| } |
| |
| ///////////////////////////////////////////////////// |
| |
| void testgoto() |
| { |
| int i; |
| |
| i = 3; |
| goto L4; |
| L3: i++; |
| goto L5; |
| L4: goto L3; |
| L5: assert(i == 4); |
| } |
| |
| int testswitch() |
| { |
| int i; |
| |
| i = 3; |
| switch (i) |
| { |
| case 0: |
| case 1: |
| default: |
| assert(0); |
| case 3: |
| break; |
| } |
| return 0; |
| } |
| |
| void testdo() |
| { |
| int x = 0; |
| |
| do |
| { |
| x++; |
| } while (x < 10); |
| printf("x == %d\n", x); |
| assert(x == 10); |
| } |
| |
| |
| void testbreak() |
| { int i, j; |
| |
| Louter: |
| for (i = 0; i < 10; i++) |
| { |
| for (j = 0; j < 10; j++) |
| { |
| if (j == 3) |
| break Louter; |
| } |
| } |
| |
| printf("i = %d, j = %d\n", i, j); |
| assert(i == 0); |
| assert(j == 3); |
| } |
| |
| /////////////////////// |
| |
| int foo(string s) |
| { |
| int i; |
| |
| i = 0; |
| switch (s) |
| { |
| case "hello": |
| i = 1; |
| break; |
| case "goodbye": |
| i = 2; |
| break; |
| case "goodb": |
| i = 3; |
| break; |
| default: |
| i = 10; |
| break; |
| } |
| return i; |
| } |
| |
| |
| void teststringswitch() |
| { int i; |
| |
| i = foo("hello"); |
| printf("i = %d\n", i); |
| assert(i == 1); |
| |
| i = foo("goodbye"); |
| printf("i = %d\n", i); |
| assert(i == 2); |
| |
| i = foo("goodb"); |
| printf("i = %d\n", i); |
| assert(i == 3); |
| |
| i = foo("huzzah"); |
| printf("i = %d\n", i); |
| assert(i == 10); |
| } |
| |
| |
| /////////////////////// |
| |
| struct Foo |
| { |
| int a; |
| char b; |
| long c; |
| } |
| |
| Foo test(Foo f) |
| { |
| f.a += 1; |
| f.b += 3; |
| f.c += 4; |
| return f; |
| } |
| |
| |
| void teststrarg() |
| { |
| Foo g; |
| g.a = 1; |
| g.b = 2; |
| g.c = 3; |
| |
| Foo q; |
| q = test(g); |
| assert(q.a == 2); |
| assert(q.b == 5); |
| assert(q.c == 7); |
| } |
| |
| /////////////////////// |
| |
| align (1) struct Foo1 |
| { |
| align (1): |
| int a; |
| char b; |
| long c; |
| } |
| |
| struct Foo2 |
| { |
| int a; |
| char b; |
| long c; |
| } |
| |
| struct Foo3 |
| { |
| int a; |
| align (1) char b; |
| long c; |
| } |
| |
| struct Foo4 |
| { |
| int a; |
| struct { char b; } |
| long c; |
| } |
| |
| void testsizes() |
| { |
| printf("%zd\n", Foo1.sizeof); |
| assert(Foo1.a.offsetof == 0); |
| assert(Foo1.b.offsetof == 4); |
| assert(Foo1.c.offsetof == 5); |
| assert(Foo1.sizeof == 13); |
| |
| assert(Foo2.a.offsetof == 0); |
| assert(Foo2.b.offsetof == 4); |
| assert(Foo2.c.offsetof == 8); |
| assert(Foo2.sizeof == 16); |
| |
| assert(Foo3.a.offsetof == 0); |
| assert(Foo3.b.offsetof == 4); |
| assert(Foo3.c.offsetof == 8); |
| assert(Foo3.b.sizeof == 1); |
| assert(Foo3.sizeof == 16); |
| |
| assert(Foo4.sizeof == 16); |
| } |
| |
| /////////////////////// |
| |
| size_t cond11565(size_t val) |
| { |
| return val ? size_t.max : 0; |
| } |
| |
| void test11565() |
| { |
| assert(cond11565(true) == size_t.max); |
| } |
| |
| /////////////////////// |
| |
| int[3] array1 = [1:1,2,0:3]; |
| |
| void testarrayinit() |
| { |
| assert(array1[0] == 3); |
| assert(array1[1] == 1); |
| assert(array1[2] == 2); |
| } |
| |
| /////////////////////// |
| |
| void test13023(ulong n) |
| { |
| static void func(bool b) {} |
| |
| ulong k = 0; |
| |
| func(k >= n / 2); |
| |
| if (k >= n / 2) |
| assert(0); |
| } |
| |
| /////////////////////// |
| |
| struct U { int a; union { char c; int d; } long b; } |
| |
| U f = { b:3, d:0x22222222, a:1 }; |
| |
| void testU() |
| { |
| assert(f.b == 3); |
| assert(f.d == 0x22222222); |
| assert(f.c == 0x22); |
| assert(f.a == 1); |
| assert(f.sizeof == 16); |
| assert(U.sizeof == 16); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void vfunc() {} |
| |
| void test12095(int k) |
| { |
| int e = 0; |
| e ? k || assert(0) : !e || vfunc(); |
| e ? k || assert(0) : e && vfunc(); |
| !e ? !e || vfunc() : k || assert(0); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| bool test3918a( float t, real u ) |
| { |
| printf("%Lf\n", u ); |
| return t && u; |
| } |
| |
| bool test3918b( real t, float u ) |
| { |
| printf("%Lf\n", t ); |
| return t && u; |
| } |
| |
| void test3918() |
| { |
| assert(test3918a(float.nan, real.nan)); |
| assert(test3918b(real.nan, float.nan)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| T docond1(T)(T l, ubyte thresh, ubyte val) { |
| l += (thresh < val); |
| return l; |
| } |
| |
| T docond2(T)(T l, ubyte thresh, ubyte val) { |
| l -= (thresh >= val); |
| return l; |
| } |
| |
| T docond3(T)(T l, ubyte thresh, ubyte val) { |
| l += (thresh >= val); |
| return l; |
| } |
| |
| T docond4(T)(T l, ubyte thresh, ubyte val) { |
| l -= (thresh < val); |
| return l; |
| } |
| |
| void testdocond() |
| { |
| assert(docond1!ubyte(10,3,5) == 11); |
| assert(docond1!ushort(10,3,5) == 11); |
| assert(docond1!uint(10,3,5) == 11); |
| assert(docond1!ulong(10,3,5) == 11); |
| |
| assert(docond2!ubyte(10,3,5) == 10); |
| assert(docond2!ushort(10,3,5) == 10); |
| assert(docond2!uint(10,3,5) == 10); |
| assert(docond2!ulong(10,3,5) == 10); |
| |
| assert(docond3!ubyte(10,3,5) == 10); |
| assert(docond3!ushort(10,3,5) == 10); |
| assert(docond3!uint(10,3,5) == 10); |
| assert(docond3!ulong(10,3,5) == 10); |
| |
| assert(docond4!ubyte(10,3,5) == 9); |
| assert(docond4!ushort(10,3,5) == 9); |
| assert(docond4!uint(10,3,5) == 9); |
| assert(docond4!ulong(10,3,5) == 9); |
| |
| |
| assert(docond1!ubyte(10,5,3) == 10); |
| assert(docond1!ushort(10,5,3) == 10); |
| assert(docond1!uint(10,5,3) == 10); |
| assert(docond1!ulong(10,5,3) == 10); |
| |
| assert(docond2!ubyte(10,5,3) == 9); |
| assert(docond2!ushort(10,5,3) == 9); |
| assert(docond2!uint(10,5,3) == 9); |
| assert(docond2!ulong(10,5,3) == 9); |
| |
| assert(docond3!ubyte(10,5,3) == 11); |
| assert(docond3!ushort(10,5,3) == 11); |
| assert(docond3!uint(10,5,3) == 11); |
| assert(docond3!ulong(10,5,3) == 11); |
| |
| assert(docond4!ubyte(10,5,3) == 10); |
| assert(docond4!ushort(10,5,3) == 10); |
| assert(docond4!uint(10,5,3) == 10); |
| assert(docond4!ulong(10,5,3) == 10); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| struct S8658 |
| { |
| int[16385] a; |
| } |
| |
| void foo8658(S8658 s) |
| { |
| int x; |
| } |
| |
| void test8658() |
| { |
| S8658 s; |
| for(int i = 0; i < 1000; i++) |
| foo8658(s); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| uint neg(uint i) |
| { |
| return ~i + 1; |
| } |
| |
| uint com(uint i) |
| { |
| return -i - 1; |
| } |
| |
| float com(float i) |
| { |
| return -i - 1; |
| } |
| |
| uint com2(uint i) |
| { |
| return -(i + 1); |
| } |
| |
| void testnegcom() |
| { |
| assert(neg(3) == -3); |
| assert(com(3) == -4); |
| assert(com(3.0f) == -4.0f); |
| assert(com2(3) == -4); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int oror1(char c) |
| { |
| return ((((((((((cast(int) c <= 32 || cast(int) c == 46) || cast(int) c == 44) |
| || cast(int) c == 58) || cast(int) c == 59) || cast(int) c == 60) |
| || cast(int) c == 62) || cast(int) c == 34) || cast(int) c == 92) |
| || cast(int) c == 39) != 0); |
| } |
| |
| int oror2(char c) |
| { |
| return ((((((((((c <= 32 || c == 46) || c == 44) |
| || c == 58) || c == 59) || c == 60) |
| || c == 62) || c == 34) || c == 92) |
| || c == 39) != 0); |
| } |
| |
| void testoror() |
| { |
| assert(oror1(0) == 1); |
| assert(oror1(32) == 1); |
| assert(oror1(46) == 1); |
| assert(oror1(44) == 1); |
| assert(oror1(58) == 1); |
| assert(oror1(59) == 1); |
| assert(oror1(60) == 1); |
| assert(oror1(62) == 1); |
| assert(oror1(34) == 1); |
| assert(oror1(92) == 1); |
| assert(oror1(39) == 1); |
| assert(oror1(33) == 0); |
| assert(oror1(61) == 0); |
| assert(oror1(93) == 0); |
| assert(oror1(255) == 0); |
| |
| assert(oror2(0) == 1); |
| assert(oror2(32) == 1); |
| assert(oror2(46) == 1); |
| assert(oror2(44) == 1); |
| assert(oror2(58) == 1); |
| assert(oror2(59) == 1); |
| assert(oror2(60) == 1); |
| assert(oror2(62) == 1); |
| assert(oror2(34) == 1); |
| assert(oror2(92) == 1); |
| assert(oror2(39) == 1); |
| assert(oror2(33) == 0); |
| assert(oror2(61) == 0); |
| assert(oror2(93) == 0); |
| assert(oror2(255) == 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| bool bt1(int p, int a, int b) |
| { |
| return p && ((1 << b) & a); |
| } |
| |
| bool bt2(int p, long a, long b) |
| { |
| return p && ((1L << b) & a); |
| } |
| |
| void testbt() |
| { |
| assert(bt1(1,7,2) == 1); |
| assert(bt1(1,7,3) == 0); |
| |
| assert(bt2(1,0x7_0000_0000,2+32) == 1); |
| assert(bt2(1,0x7_0000_0000,3+32) == 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test13383() |
| { |
| foreach (k; 32..33) |
| { |
| if (1L & (1L << k)) |
| { |
| assert(0); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int andand1(int c) |
| { |
| return (c > 32 && c != 46 && c != 44 |
| && c != 58 && c != 59 |
| && c != 60 && c != 62 |
| && c != 34 && c != 92 |
| && c != 39) != 0; |
| } |
| |
| bool andand2(long c) |
| { |
| return (c > 32 && c != 46 && c != 44 |
| && c != 58 && c != 59 |
| && c != 60 && c != 62 |
| && c != 34 && c != 92 |
| && c != 39) != 0; |
| } |
| |
| int foox3() { return 1; } |
| |
| int andand3(uint op) |
| { |
| if (foox3() && |
| op != 7 && |
| op != 3 && |
| op != 18 && |
| op != 30 && |
| foox3()) |
| return 3; |
| return 4; |
| } |
| |
| |
| void testandand() |
| { |
| assert(andand1(0) == 0); |
| assert(andand1(32) == 0); |
| assert(andand1(46) == 0); |
| assert(andand1(44) == 0); |
| assert(andand1(58) == 0); |
| assert(andand1(59) == 0); |
| assert(andand1(60) == 0); |
| assert(andand1(62) == 0); |
| assert(andand1(34) == 0); |
| assert(andand1(92) == 0); |
| assert(andand1(39) == 0); |
| assert(andand1(33) == 1); |
| assert(andand1(61) == 1); |
| assert(andand1(93) == 1); |
| assert(andand1(255) == 1); |
| |
| assert(andand2(0) == false); |
| assert(andand2(32) == false); |
| assert(andand2(46) == false); |
| assert(andand2(44) == false); |
| assert(andand2(58) == false); |
| assert(andand2(59) == false); |
| assert(andand2(60) == false); |
| assert(andand2(62) == false); |
| assert(andand2(34) == false); |
| assert(andand2(92) == false); |
| assert(andand2(39) == false); |
| assert(andand2(33) == true); |
| assert(andand2(61) == true); |
| assert(andand2(93) == true); |
| assert(andand2(255) == true); |
| |
| assert(andand3(6) == 3); |
| assert(andand3(30) == 4); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| bool bittest11508(char c) |
| { |
| return c=='_' || c=='-' || c=='+' || c=='.'; |
| } |
| |
| void testbittest() |
| { |
| assert(bittest11508('_')); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| uint or1(ubyte x) |
| { |
| return x | (x<<8) | (x<<16) | (x<<24) | (x * 3); |
| } |
| |
| void testor_combine() |
| { |
| printf("%x\n", or1(1)); |
| assert(or1(5) == 5 * (0x1010101 | 3)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| int shrshl(int i) { |
| return ((i+1)>>1)<<1; |
| } |
| |
| void testshrshl() |
| { |
| assert(shrshl(6) == 6); |
| assert(shrshl(7) == 8); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| bool bt10715(in uint[] ary, size_t bitnum) |
| { |
| return !!(ary[bitnum >> 5] & 1 << (bitnum & 31)); // uses bt |
| } |
| |
| bool neg_bt10715(in uint[] ary, size_t bitnum) |
| { |
| return !(ary[bitnum >> 5] & 1 << (bitnum & 31)); // does not use bt |
| } |
| |
| void test10715() |
| { |
| static uint[2] a1 = [0x1001_1100, 0x0220_0012]; |
| |
| if ( bt10715(a1,30)) assert(0); |
| if (!bt10715(a1,8)) assert(0); |
| if ( bt10715(a1,30+32)) assert(0); |
| if (!bt10715(a1,1+32)) assert(0); |
| |
| if (!neg_bt10715(a1,30)) assert(0); |
| if ( neg_bt10715(a1,8)) assert(0); |
| if (!neg_bt10715(a1,30+32)) assert(0); |
| if ( neg_bt10715(a1,1+32)) assert(0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| ptrdiff_t compare12164(A12164* rhsPA, A12164* zis) |
| { |
| if (*rhsPA == *zis) |
| return 0; |
| return ptrdiff_t.min; |
| } |
| |
| struct A12164 |
| { |
| int a; |
| } |
| |
| void test12164() |
| { |
| auto a = A12164(3); |
| auto b = A12164(2); |
| assert(compare12164(&a, &b)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int foo10678(char[5] txt) |
| { |
| return txt[0] + txt[1] + txt[4]; |
| } |
| |
| void test10678() |
| { |
| char[5] hello = void; |
| hello[0] = 8; |
| hello[1] = 9; |
| hello[4] = 10; |
| int i = foo10678(hello); |
| assert(i == 27); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| struct S12051 |
| { |
| this(char c) |
| { |
| assert(c == 'P' || c == 'M'); |
| } |
| } |
| |
| void test12051() |
| { |
| auto ip = ["abc"]; |
| foreach (i, s; ip) |
| { |
| S12051(i < ip.length ? 'P' : 'M'); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void bug7565( double x) { assert(x == 3); } |
| |
| void test7565() |
| { |
| double y = 3; |
| bug7565( y++ ); |
| assert(y == 4); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int bug8525(int[] devt) |
| { |
| return devt[$ - 1]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void func13190(int) {} |
| |
| struct Struct13190 |
| { |
| ulong a; |
| uint b; |
| }; |
| |
| __gshared Struct13190* table13190 = |
| [ |
| Struct13190(1, 1), |
| Struct13190(0, 2) |
| ]; |
| |
| void test13190() |
| { |
| for (int i = 0; table13190[i].a; i++) |
| { |
| ulong tbl = table13190[i].a; |
| func13190(i); |
| if (1 + tbl) |
| { |
| if (tbl == 0x80000) |
| return; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| double foo13485(double c, double d) |
| { |
| // This must not be optimized to c += (d + d) |
| c += d; |
| c += d; |
| return c; |
| } |
| |
| void test13485() |
| { |
| enum double d = 0X1P+1023; |
| assert(foo13485(-d, d) == d); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test12833a(int a) |
| { |
| long x = cast(long)a; |
| |
| switch (cast(int)(cast(ushort)(x >> 16 & 65535L))) |
| { |
| case 1: |
| { |
| break; |
| } |
| default: |
| { |
| assert(0); |
| } |
| } |
| } |
| |
| void test12833() |
| { |
| test12833a(0x1_0000); |
| } |
| |
| /***********************************************/ |
| |
| struct Point9449 |
| { |
| double f = 3.0; |
| double g = 4.0; |
| } |
| |
| void test9449() |
| { |
| Point9449[1] arr; |
| if (arr[0].f != 3.0) assert(0); |
| if (arr[0].g != 4.0) assert(0); |
| } |
| |
| struct Point9449x |
| { |
| float f = 0.0; |
| double g = 0.0; |
| } |
| |
| void test9449x() |
| { |
| Point9449x[1] arr; |
| if (arr[0].f != 0.0) assert(0); |
| if (arr[0].g != 0.0) assert(0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=12057 |
| |
| bool prop12057(real x) { return false; } |
| double f12057(real) { return double.init; } |
| void test12057() |
| { |
| real fc = f12057(real.init); |
| if (fc == 0 || fc.prop12057) {} |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| long modulo24 (long ticks) |
| { |
| ticks %= 864000000000; |
| if (ticks < 0) |
| ticks += 864000000000; |
| return ticks; |
| } |
| |
| void test13784() |
| { |
| assert (modulo24(-141600000000) == 722400000000); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| struct S13969 { |
| int x, y; |
| } |
| |
| int test13969(const S13969* f) { |
| return 0 % ((f.y > 0) ? f.x / f.y : f.x / -f.y); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int[] arr14436; |
| void test14436() |
| { |
| assert(arr14436 == null); |
| arr14436 = [1, 2, 3]; |
| assert(arr14436 != null); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test14220() |
| { |
| auto a = toString(14); |
| |
| printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length); |
| return; |
| } |
| |
| auto toString(int value) |
| { |
| uint mValue = value; |
| |
| char[int.sizeof * 3] buffer = void; |
| size_t index = buffer.length; |
| |
| do |
| { |
| uint div = cast(int)(mValue / 10); |
| char mod = mValue % 10 + '0'; |
| buffer[--index] = mod; // Line 22 |
| mValue = div; |
| } while (mValue); |
| |
| //printf("buffer.ptr = %p, index = %d\n", buffer.ptr, cast(int)index); |
| return dup(buffer[index .. $]); |
| } |
| |
| char[] dup(char[] a) |
| { |
| //printf("a.ptr = %p, a.length = %d\n", a.ptr, cast(int)a.length); |
| a[0] = 1; // segfault |
| return a; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int stripLeft(int str, int dc) |
| { |
| while (true) |
| { |
| int a = str; |
| int s = a; |
| str += 1; |
| if (dc) return s; |
| } |
| } |
| |
| void test14829() |
| { |
| if (stripLeft(3, 1) != 3) // fails with -O |
| assert(0); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test3() |
| { |
| int[6] a; |
| int[] b; |
| b = a; |
| b = (b.ptr + b.length - 5)[0 .. b.ptr + b.length - 1 - a.ptr]; |
| assert(b.ptr == a.ptr + 1); |
| assert(b.length == 5); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=14782 |
| |
| |
| void test14782() |
| { |
| static struct Foo |
| { |
| long a = 8; |
| int b = 7; |
| } |
| |
| static Foo[1] fun() { Foo[1] a; return a; } |
| |
| auto result = fun(); |
| assert(result[0].a == 8); |
| assert(result[0].b == 7); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test14987() |
| { |
| static struct Foo |
| { |
| int b = 7; |
| } |
| static assert((Foo[4]).sizeof == 16); |
| |
| static Foo[4] fun() { Foo[4] a; return a; } |
| |
| auto result = fun(); |
| assert(result[0].b == 7); |
| assert(result[1].b == 7); |
| assert(result[2].b == 7); |
| assert(result[3].b == 7); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void[] calloc15272(size_t bc) nothrow pure |
| { |
| assert(bc == 1); |
| return new void[1]; |
| } |
| |
| void test15272() |
| { |
| void[] scache = cast(void[])"abc"; |
| size_t count = 1; |
| void[]* buckets = &scache; |
| *buckets = calloc15272(count)[0 .. count]; |
| } |
| |
| /***************************************** |
| * https://issues.dlang.org/show_bug.cgi?id=15861 |
| */ |
| |
| void test15861() |
| { |
| double val = 4286853117.; |
| |
| (){ |
| assert(val == 4286853117.); |
| }(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=15629 comment 3 |
| // -O |
| |
| void test15629() |
| { |
| int[] a = [3]; |
| int value = a[0] >= 0 ? a[0] : -a[0]; |
| assert(a[0] == 3); |
| writeln(value, a); |
| } |
| |
| void writeln(int v, int[] a) |
| { |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| real binPosPow2() { return 1.0L; } |
| |
| real binPow2() |
| { |
| return 1.0L/binPosPow2(); |
| } |
| |
| void test4() |
| { |
| assert(binPow2() == 1.0L); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=13474 |
| |
| |
| double sumKBN(double s = 0.0) |
| { |
| import core.math : fabs; |
| double c = 0.0; |
| foreach(double x; [1, 1e100, 1, -1e100]) |
| { |
| x = multiply(x); |
| double t = s + x; |
| if(s.fabs >= x.fabs) |
| { |
| double y = s-t; |
| c += y+x; |
| } |
| else |
| { |
| double y = x-t; |
| c += y+s; |
| } |
| s = t; |
| } |
| return s + c; |
| } |
| |
| double multiply(double a) { return a * 10000; } |
| |
| void test13474() |
| { |
| double r = 20000; |
| assert(r == sumKBN()); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=16699 |
| |
| ulong[1] parseDateRange() |
| { |
| try |
| { |
| ulong[1] result; |
| result[0] = 6; |
| return result; |
| } |
| finally |
| { |
| } |
| } |
| |
| void test16699() |
| { |
| ulong[1] range = parseDateRange(); |
| assert(range[0] == 6); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=16102 |
| |
| struct S16102 { ~this() { } } |
| |
| long[1] f16102() |
| { |
| S16102 a; |
| return [1]; |
| } |
| |
| void test16102() |
| { |
| assert( f16102() == [1] ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test5a(ulong x, ulong y) |
| { |
| int a; |
| if (x >> 32) |
| a = 1; |
| else |
| a = 2; |
| assert(a == 1); |
| |
| if (y >> 32) |
| a = 1; |
| else |
| a = 2; |
| assert(a == 2); |
| } |
| |
| void test5() |
| { |
| test5a(uint.max + 1L, uint.max); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| /* Test the pattern: |
| * replace (e ? i1 : i2) with (i1 + e * (i2 - i1)) |
| * when e1 is 0 or 1 and (i2-i1) is a power of 2. |
| */ |
| |
| int foo61(int i) |
| { |
| return (i % 2 != 0) ? 4 : 2; |
| } |
| |
| int foo62(int i) |
| { |
| return (i % 2 != 0) ? 2 : 4; |
| } |
| |
| bool bar6(bool b) { return b; } |
| |
| int foo63(bool b) |
| { |
| return bar6(b) ? 16 : 8; |
| } |
| |
| int foo64(bool b) |
| { |
| return bar6(b) ? 8 : 16; |
| } |
| |
| void test6() |
| { |
| if (foo61(0) != 2) assert(0); |
| if (foo61(1) != 4) assert(0); |
| if (foo62(0) != 4) assert(0); |
| if (foo62(1) != 2) assert(0); |
| if (foo63(0) != 8) assert(0); |
| if (foo63(1) != 16) assert(0); |
| if (foo64(0) != 16) assert(0); |
| if (foo64(1) != 8) assert(0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int dataflow(int b) { |
| int ret; |
| |
| if (b==4) |
| ret = 3; |
| else |
| ret = 5; |
| |
| if (ret == 4) |
| return 0; |
| else |
| return 1; |
| } |
| |
| void testeqeqranges() |
| { |
| int i = dataflow(4); |
| if (i != 1) |
| assert(0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=16189 |
| |
| void test16189() |
| { |
| ubyte[9][1] data; |
| uint a = 0; |
| loop: |
| data[0] = data[a]; |
| a--; |
| bool b = false; |
| if (b) goto loop; |
| assert(a == -1); // was failing with -O |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=16997 |
| |
| void test16997() |
| { |
| /* Exhaustively test all signed and unsigned byte promotions for |
| * - + and ~ |
| */ |
| for (int i = 0; i < 256; ++i) |
| { |
| ubyte c = cast(ubyte)i; |
| |
| int i1 = cast(int)(~c); |
| int i2 = cast(int)(~cast(int)c); |
| |
| //printf("%d, %d\n", i1, i2); |
| assert(i1 == i2); |
| |
| i1 = cast(int)(+c); |
| i2 = cast(int)(+cast(int)c); |
| assert(i1 == i2); |
| |
| i1 = cast(int)(-c); |
| i2 = cast(int)(-cast(int)c); |
| assert(i1 == i2); |
| } |
| |
| for (int i = 0; i < 256; ++i) |
| { |
| byte c = cast(byte)i; |
| |
| int i1 = cast(int)(~c); |
| int i2 = cast(int)(~cast(int)c); |
| |
| //printf("%d, %d\n", i1, i2); |
| assert(i1 == i2); |
| |
| i1 = cast(int)(+c); |
| i2 = cast(int)(+cast(int)c); |
| assert(i1 == i2); |
| |
| i1 = cast(int)(-c); |
| i2 = cast(int)(-cast(int)c); |
| assert(i1 == i2); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test18315() // https://issues.dlang.org/show_bug.cgi?id=18315 |
| { |
| int i = int.min; |
| bool b = i > 0; |
| assert(!b); |
| b = 0 < i; |
| assert(!b); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=18461 |
| |
| void test18461() |
| { |
| import core.bitop; |
| |
| size_t test_val = 0b0001_0000; |
| |
| if (bt(&test_val, 4) == 0) |
| assert(false); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test18730() // https://issues.dlang.org/show_bug.cgi?id=18730 |
| { |
| static if (size_t.sizeof == 8) |
| { |
| static int bt18730_64_64(in ulong* p, ulong bitnum) pure @system |
| { |
| return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0; |
| } |
| static int bt18730_64_32(in ulong* p, uint bitnum) pure @system |
| { |
| return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0; |
| } |
| static int bt18730_32_64(in uint* p, ulong bitnum) pure @system |
| { |
| return ((p[bitnum >> 5] & (1 << (bitnum & 31)))) != 0; |
| } |
| |
| // Check that bt_64_64 uses a 64-bit register for the offset. |
| { |
| enum bitIndex = int.max + 1L; |
| auto a = new ulong[](bitIndex / 64 + 1); |
| a[bitIndex / 64] = 1; |
| assert(bt18730_64_64(a.ptr, bitIndex)); |
| assert(!bt18730_64_64(a.ptr, bitIndex + 1)); |
| assert(!bt18730_64_64(a.ptr, bitIndex - 1)); |
| } |
| // Check that bt_64_32 uses a 32-bit register for the offset. |
| { |
| static int f(ulong* p, ulong bitnum) |
| { |
| return bt18730_64_32(p, cast(uint) bitnum); |
| } |
| enum bitIndex = uint.max + 1L; |
| assert(cast(uint) bitIndex == 0); |
| ulong s = 1; |
| assert(f(&s, bitIndex)); |
| } |
| /* Check that bt_32_64 does not become a 64-bit bt instruction. Would lead |
| to a segfault when trying to load 8 bytes while only 4 are accessible. */ |
| version (Posix) |
| {{ |
| import core.sys.posix.sys.mman; |
| import core.sys.posix.unistd; |
| // Allocate two pages. |
| immutable sz = 2 * sysconf(_SC_PAGESIZE); |
| auto m = mmap(null, sz, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0); |
| // Discard the higher page. It becomes unreadable. |
| munmap(m + sz / 2, sz / 2); |
| // Try looking at the last 4 bytes of the readable page. |
| uint* p = cast(uint*) (m + sz / 2 - uint.sizeof); |
| bt18730_32_64(p, 0); |
| munmap(m, sz / 2); // Free the readable page. |
| }} |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void test19497() // https://issues.dlang.org/show_bug.cgi?id=19497 |
| { |
| { |
| ubyte[1024] data; |
| ushort* ushortPtr = cast(ushort*) data.ptr; |
| *ushortPtr++ = 0xfe00; |
| printf("ushortPtr(%p)\n", ushortPtr); |
| fflush(stdout); |
| } |
| |
| alias Seq(stuff ...) = stuff; |
| static foreach (T; Seq!(ubyte, ushort, uint, ulong, byte, short, int, long)) |
| {{ |
| T[2] data = 0x2A; |
| T* q = &data[0]; |
| *q++ = cast(T) 0x1122334455667788; |
| if (*q != 0x2A) assert(false); |
| }} |
| |
| { |
| static int toStringz(string s) { return s.length > 0 ? s[0] : 0; } |
| static void toAStringz(in string[] a, int* az) |
| { |
| foreach (string s; a) |
| { |
| *az++ = toStringz(s); |
| } |
| } |
| string[1] sa = ["abc"]; |
| int[2] tgt = 0x2a; |
| toAStringz(sa[], tgt.ptr); |
| if (tgt[0] != 'a') assert(false); |
| if (tgt[1] != 0x2a) assert(false); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=18794 |
| |
| bool method18794(size_t* p) |
| { |
| int bitIdx = 0; |
| func18794(); |
| return (*p & (1UL << bitIdx)) != 0; |
| } |
| |
| void func18794() {} |
| |
| void prep18794() |
| { |
| asm {} |
| ulong[2] x = -1; |
| } |
| |
| void test18794() |
| { |
| prep18794(); |
| size_t s; |
| method18794(&s); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| /* Test the optimization |
| * (e1+c)-e2 => (e1-e2)+c |
| */ |
| |
| void testelmin() |
| { |
| static void foo(int i) |
| { |
| static ubyte[4] bar() |
| { |
| ubyte[4] array; |
| foreach (i, ref a; array) |
| a = cast(ubyte)(i + 1); |
| return array; |
| } |
| |
| static void test(int i, ubyte* p) |
| { |
| foreach (j; 0 .. 4) |
| assert(p[i * 4 + j] == j + 1); |
| } |
| |
| ubyte[32] data; |
| data[i*4..(i+1)*4] = bar(); // optimize to single MOV |
| |
| test(i, data.ptr); |
| } |
| |
| foo(4); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| const(char)* fastpar(string s) |
| { |
| return s.ptr + s.length; |
| } |
| |
| void testfastpar() |
| { |
| string s = "abcde"; |
| auto p = fastpar(s); |
| assert(*p == 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=20363 |
| |
| ulong foo20363(double d) |
| { |
| ulong u = * cast(ulong*) &d; |
| return (u >> 1) & 1; |
| } |
| |
| void test20363() |
| { |
| ulong u = 0b10; |
| if (foo20363(*cast(double*) &u) == 0) |
| assert(false); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| T testfooa(T)(T value) |
| { |
| return 10 - (value * 57); // gets rewritten into (value*-57)+10 |
| } |
| |
| T testfoob(T)(T value) |
| { |
| return (value * -57) + 10; |
| } |
| |
| void testNegConst() |
| { |
| assert(testfooa(1) == -47); |
| assert(testfoob(1) == -47); |
| assert(testfooa(1.0) == -47); |
| assert(testfoob(1.0) == -47); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=16317 |
| |
| int add8ret3(ref int s) |
| { |
| s += 8; |
| return 3; |
| } |
| |
| int binAdd(int val) |
| { |
| val = val + add8ret3(val); |
| return val; |
| } |
| |
| void test16317() |
| { |
| assert(binAdd(1) == (1 + 3)); |
| static assert(binAdd(1) == (1 + 3)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=20050 |
| |
| int test20050_g = 0; |
| void test20050_impure_function_1() { ++test20050_g; } |
| void function() test20050_get_impure_function() pure |
| { |
| static void impure_function_2() |
| { |
| ++test20050_g; |
| test20050_impure_function_1(); |
| } |
| return &impure_function_2; |
| } |
| void test20050() |
| { |
| auto f = test20050_get_impure_function(); |
| f(); |
| assert(test20050_g == 2); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://github.com/dlang/dmd/pull/11238 |
| |
| int testCpStatic1(int y) |
| { |
| __gshared int yyy = 7; |
| auto x = yyy; // no copy-propagation |
| if (y) |
| return x; |
| return x + 3; |
| } |
| |
| void testCpStatic() |
| { |
| assert(testCpStatic1(1) == 7); |
| assert(testCpStatic1(0) == 10); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=20991 |
| |
| int x7; |
| |
| void bar7(int i) |
| { |
| assert(i == x7); |
| ++x7; |
| } |
| |
| void test7() |
| { |
| for (int i = 0; i <= 1; ++i) |
| bar7(i); |
| assert(x7 == 2); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://github.com/dlang/dmd/pull/11388 |
| |
| ushort byteswap(ushort x) pure |
| { |
| // Should be detected and XCHG instruction generated |
| return cast(ushort) (((x >> 8) & 0xFF) | ((x << 8) & 0xFF00u)); |
| } |
| |
| void testbyteswap() |
| { |
| assert(byteswap(0xF234) == 0x34F2); |
| static ushort xx = 0xF234; |
| assert(byteswap(xx) == 0x34F2); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // These should all be recognized by the compiler and generate ROL or ROR |
| // instructions. |
| |
| uint rol32(uint x, uint n) |
| { |
| return (x << n) | (x >> (32 - n)); |
| } |
| |
| uint ror32(uint x, uint n) |
| { |
| return (x >> n) | (x << (32 - n)); |
| } |
| |
| ulong rol64(ulong x, uint n) |
| { |
| return (x << n) | (x >> (64 - n)); |
| } |
| |
| ulong ror64(ulong x, uint n) |
| { |
| return (x >> n) | (x << (64 - n)); |
| } |
| |
| void testrolror() |
| { |
| assert(ror32(0x0123_4567u, 4) == 0x7012_3456); |
| assert(rol32(0x7012_3456u, 4) == 0x0123_4567); |
| |
| assert(ror64(0x0123_4567_89AB_CDEFuL, 4) == 0xF012_3456_789A_BCDE); |
| assert(rol64(0xF012_3456_789A_BCDEuL, 4) == 0x0123_4567_89AB_CDEF); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=20162 |
| |
| void test20162() |
| { |
| static long f(long a) |
| { |
| assert(a == -1L); |
| return a; |
| } |
| |
| foreach (i; 1 .. 2) |
| { |
| foreach (j; 0 .. 2) |
| { |
| printf("%d %d %llx\n", i, |
| ((i != 0) ? -1 : +1), |
| f((i != 0) ? -1 : +1)); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=3713 |
| |
| int star1(int i) |
| { |
| return i ? star1(i - 1) : 0; |
| } |
| |
| int star2(int i) |
| { |
| return i == 0 ? 0 : star2(i - 1); |
| } |
| |
| int star3(int i) |
| { |
| if (i == 0) |
| return 0; |
| return i == 2 ? star3(i - 2) : star3(i - 1); |
| } |
| |
| int star4(int i) |
| { |
| return (i == 0) ? 0 |
| : i != 2 ? star4(i - 1) |
| : star4(i - 2); |
| } |
| |
| void test3713() |
| { |
| assert(star1(10) == 0); |
| assert(star2(10) == 0); |
| assert(star3(10) == 0); |
| assert(star4(10) == 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| void testsbbrex() |
| { |
| // special code is generated for these two cases |
| static long foolt(dchar c) |
| { |
| return c < 0x10000 ? 1 : 2; |
| } |
| |
| static long fooge(uint c) |
| { |
| return c >= 0x10000 ? 1L : 2L; |
| } |
| |
| assert(foolt(0) == 1); |
| assert(foolt(0x10000) == 2); |
| assert(fooge(0) == 2); |
| assert(fooge(0x10000) == 1); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // https://issues.dlang.org/show_bug.cgi?id=19846 |
| |
| alias Void = byte[0]; |
| static immutable Void VOID; // = []; |
| |
| __gshared int x19846; |
| |
| Void print19846() |
| { |
| //printf("This should print\n"); |
| x19846 = 3; |
| return VOID; |
| } |
| |
| Void identity19846(Void value, out int i) |
| { |
| i = 7; |
| return value; |
| } |
| |
| void test19846() |
| { |
| int i; |
| identity19846(print19846(), i); |
| //printf("i = %d\n", i); |
| assert(x19846 == 3); |
| assert(i == 7); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| // Some tests for OPmemcpy |
| |
| enum N = 128; |
| |
| ubyte[N] def() |
| { |
| ubyte[N] array; |
| foreach (i, ref a; array) |
| a = cast(ubyte)(i + 1); |
| return array; |
| } |
| |
| |
| void ghi(ubyte* p) |
| { |
| foreach (i; 0 .. N) |
| assert(p[i] == i + 1); |
| } |
| |
| void testmemcpy() |
| { |
| ubyte[N] bits; |
| ubyte[N] bits2; |
| bits2[0..N] = bits[0..N] = def(); |
| ghi(bits.ptr); |
| ghi(bits2.ptr); |
| |
| __gshared size_t n = N; |
| ubyte[N] bits3; |
| ubyte[N] bits4; |
| bits4[0..n] = bits3[0..n] = def(); |
| ghi(bits3.ptr); |
| ghi(bits4.ptr); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| /* Test all the cases of uses of LEA for multiplication by a constant |
| */ |
| |
| T testlea(uint C, T)(T x, T y) |
| { |
| y = y * C; // cdmul() |
| x *= C; // cdmulass() |
| return x + y; |
| } |
| |
| void testleax(uint C)(uint X, uint Y) |
| { |
| assert(testlea!C(X,Y) == C * (X + Y)); |
| assert(testlea!C(cast(long)X,cast(long)Y) == cast(long)C*X + cast(long)C*Y); |
| } |
| |
| void testMulLea() |
| { |
| testleax!3(10,11); |
| testleax!5(10,11); |
| testleax!6(10,11); |
| testleax!9(10,11); |
| |
| testleax!10(10,11); |
| testleax!12(10,11); |
| testleax!18(10,11); |
| testleax!20(10,11); |
| testleax!24(10,11); |
| testleax!36(10,11); |
| testleax!40(10,11); |
| testleax!72(10,11); |
| |
| testleax!37(10,11); |
| testleax!74(10,11); |
| testleax!13(10,11); |
| testleax!26(10,11); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| /* Test *= of register pair |
| */ |
| |
| void testMulAssPair() |
| { |
| static ulong pow(ulong x, int m) |
| { |
| ulong v = x; |
| ulong p = 1; |
| while (1) |
| { |
| if (m & 1) |
| p *= v; |
| m >>= 1; |
| if (!m) |
| break; |
| v *= v; |
| } |
| return p; |
| } |
| |
| enum ulong e_10_pow_19 = 10uL^^19; |
| assert(e_10_pow_19 == pow(10uL, 19)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21038 |
| |
| const(wchar)* x21038 = "xz"; |
| const(dchar)* name21038 = "abcd"; |
| |
| void test21038() |
| { |
| assert((cast(size_t) x21038) % wchar.sizeof == 0); |
| assert((cast(size_t) name21038) % dchar.sizeof == 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21325 |
| |
| real f21325(const real x) pure @safe nothrow @nogc |
| { |
| return (x != 0.0L) ? x : real.nan; |
| } |
| |
| void test21325() @safe |
| { |
| ulong x = 0uL; |
| while(true) |
| { |
| const y = f21325(x); // should set y to real.nan |
| |
| assert(y != y); |
| |
| if (++x) |
| return; // good |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=16274 |
| |
| extern(C) int pair(short a, ushort b, byte c, ubyte d); |
| |
| struct S |
| { |
| // provide alternate implementation of .pair() |
| pragma(mangle, "pair") |
| extern(C) static void pair(int a, int b, int c, int d) |
| { |
| //printf("%d %d %d %d\n", a, b, c, d); |
| assert(a == -1); |
| assert(b == 2); |
| assert(c == -3); |
| assert(d == 4); |
| } |
| } |
| |
| void test16274() |
| { |
| version (X86_64) |
| pair(-1, 2, -3, 4); |
| version (X86) |
| pair(-1, 2, -3, 4); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=16268 |
| |
| void test16268() |
| { |
| static void f(byte x) |
| { |
| for (byte i = 0; i <= x && i >= 0; ++i) |
| { |
| assert(i >= 0); |
| assert(i != -1); |
| //printf("%d\n", i); |
| } |
| } |
| |
| f(byte.max); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=11435 |
| |
| void test11435a() |
| { |
| alias T = byte; |
| |
| static void fun(T c, T b, int v) |
| { |
| } |
| |
| static void abc(T[] b) |
| { |
| fun(b[0], b[1], 0); |
| } |
| |
| version(Windows) |
| { |
| import core.sys.windows.windows; |
| auto p = VirtualAlloc(null, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
| } |
| else |
| { |
| import core.sys.posix.sys.mman; |
| auto p = mmap(null, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0L); |
| } |
| assert(p); |
| auto px = (cast(T*)(p + 4096 - 2 * T.sizeof)); |
| abc(px[0..2]); |
| } |
| |
| void test11435b() |
| { |
| import core.sys.windows.windows; |
| alias T = short; |
| |
| static void fun(T c, T b, int v) |
| { |
| } |
| |
| static void abc(T[] b) |
| { |
| fun(b[0], b[1], 0); |
| } |
| |
| version(Windows) |
| { |
| import core.sys.windows.windows; |
| auto p = VirtualAlloc(null, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
| } |
| else |
| { |
| import core.sys.posix.sys.mman; |
| auto p = mmap(null, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0L); |
| } |
| assert(p); |
| auto px = (cast(T*)(p + 4096 - 2 * T.sizeof)); |
| abc(px[0..2]); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21513 |
| |
| struct Stuff |
| { |
| size_t c; // declare after items and not crash ! |
| ubyte[1] items; |
| } |
| |
| void grow(ref Stuff stuff) |
| { |
| with (stuff) |
| { |
| const oldCapacity = c; |
| items.ptr[0..oldCapacity] = items.ptr[0..0]; // use literal 0 instead of |
| items.ptr[0] = 0; // oldcapacity and no crash ! |
| } |
| } |
| |
| void test21513() |
| { |
| Stuff stuff; |
| grow(stuff); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21526 |
| |
| double f21256(double a, double b) { |
| double c = a + b; |
| return c; |
| } |
| |
| void test21256() |
| { |
| union DX |
| { |
| double d; |
| ulong l; |
| } |
| |
| DX a, b; |
| a.l = 0x4341c37937e08000; |
| b.l = 0x4007ffcb923a29c7; |
| |
| DX r; |
| r.d = f21256(a.d, b.d); |
| //if (r.d != 0x1.1c37937e08001p+53) |
| //printf("r = %A should be 0x1.1c37937e08001p+53 %A\n", r.d, 0x1.1c37937e08001p+53); |
| //assert(r == 0x1.1c37937e08001p+53); |
| |
| // cannot seem to get the two to produce the same value |
| assert(r.l == 0x4341c37937e08001 || // value using XMM |
| r.l == 0x4341c37937e08002); // value using x87 |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21816 |
| |
| bool test21816a(float t) |
| { |
| return cast(bool)t; |
| } |
| |
| void test21816() |
| { |
| assert(test21816a(float.nan)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // https://issues.dlang.org/show_bug.cgi?id=21835 |
| |
| struct Point21835 |
| { |
| float f = 3.0; |
| double d = 4.0; |
| real r = 5.0; |
| } |
| |
| void test21835y() |
| { |
| Point21835[1] arr; |
| if (arr[0].f != 3.0) assert(0); |
| if (arr[0].d != 4.0) assert(0); |
| if (arr[0].r != 5.0) assert(0); |
| } |
| |
| struct Point21835x |
| { |
| float f = 0.0; |
| double d = 0.0; |
| real r = 0.0; |
| } |
| |
| void test21835() |
| { |
| test21835y(); |
| Point21835x[1] arr; |
| if (arr[0].f != 0.0) assert(0); |
| if (arr[0].d != 0.0) assert(0); |
| if (arr[0].r != 0.0) assert(0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| int main() |
| { |
| // All the various integer divide tests |
| testsdiv2(); |
| testulldiv(); |
| testfastudiv(); |
| testsldiv(); |
| testslmod(); |
| testfastdiv(); |
| testdivdiv(); |
| testdivcmp(); |
| |
| testgoto(); |
| testswitch(); |
| testdo(); |
| testbreak(); |
| teststringswitch(); |
| teststrarg(); |
| test12164(); |
| testsizes(); |
| testarrayinit(); |
| testU(); |
| testbittest(); |
| test8658(); |
| test3918(); |
| test12051(); |
| testdocond(); |
| testnegcom(); |
| test11565(); |
| testoror(); |
| testbt(); |
| test12095(0); |
| testandand(); |
| testor_combine(); |
| testshrshl(); |
| test13383(); |
| test13190(); |
| test13485(); |
| test14436(); |
| test10715(); |
| test10678(); |
| test7565(); |
| test13023(0x10_0000_0000); |
| test12833(); |
| test9449(); |
| test9449x(); |
| test12057(); |
| test13784(); |
| test14220(); |
| test14829(); |
| test3(); |
| test14782(); |
| test14987(); |
| test15272(); |
| test15861(); |
| test15629(); |
| test4(); |
| test13474(); |
| test16699(); |
| test16102(); |
| test5(); |
| test6(); |
| testeqeqranges(); |
| test16189(); |
| test16997(); |
| test18315(); |
| test18461(); |
| test18730(); |
| test19497(); |
| test18794(); |
| testelmin(); |
| testfastpar(); |
| test20363(); |
| testNegConst(); |
| test16317(); |
| test20050(); |
| testCpStatic(); |
| test7(); |
| testbyteswap(); |
| testrolror(); |
| test20162(); |
| test3713(); |
| testsbbrex(); |
| test19846(); |
| testmemcpy(); |
| testMulLea(); |
| testMulAssPair(); |
| test21038(); |
| test21325(); |
| test16274(); |
| test16268(); |
| test11435a(); |
| test11435b(); |
| test21513(); |
| test21256(); |
| test21816(); |
| test21835(); |
| |
| printf("Success\n"); |
| return 0; |
| } |