Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tracker] AArch64 progress #2153

Open
14 of 17 tasks
dnadlinger opened this issue Jun 5, 2017 · 66 comments
Open
14 of 17 tasks

[tracker] AArch64 progress #2153

dnadlinger opened this issue Jun 5, 2017 · 66 comments

Comments

@dnadlinger
Copy link
Member

dnadlinger commented Jun 5, 2017

I'm currently on-off working on aarch64-unknown-linux-gnu and have a large part of the test suite passing already, including std.math (IEEE 754 quad-precision real support). The idea is to get an ltsmaster compiler that passes the whole test suite first. See the log of the latest AArch64 CI builds for the current status of the test suite.

Open items:

Upstream PRs to integrate into ltsmaster:


@redstar: How is your cent work progressing?

@redstar
Copy link
Member

redstar commented Jun 5, 2017

@klickverbot I still have some trouble with the 128bit emulation code.

@dnadlinger
Copy link
Member Author

@redstar: What sort of trouble in particular?

@egrimley
Copy link

@joakim-noah
Copy link
Contributor

I've been trying out Android/AArch64, now that I have access to an Android/AArch64 tablet, with an updated version of dlang/druntime#1267 for AArch64. One oddity is that llvm doesn't invoke __tls_get_addr on linux/AArch64, which was one of the main reasons native TLS didn't work on Android/ARM, as the Android dynamic linker doesn't provide that function.

As a result, I wonder if native TLS can be made to work on Android/AArch64, though when I tried reverting my llvm patch and other ldc/druntime modifications for Walter's brand of emulated TLS, the resulting test binary would segfault when the GC called some thread-local variable. I didn't look into it further and switched to llvm's emulated TLS instead, which is what clang uses on Android/AArch64, but I'll investigate using native TLS more later.

Using llvm's emulated TLS and cross-compiling the druntime tests, I had to disable these real-related tests in core.internal.{convert,hash}:

diff --git a/src/core/internal/convert.d b/src/core/internal/convert.d
index eeb5580c..a31cbb3e 100644
--- a/src/core/internal/convert.d
+++ b/src/core/internal/convert.d
@@ -348,13 +348,13 @@ version(unittest)
         //testNumberConvert!("-double.nan"); //BUG @@@3632@@@
         testNumberConvert!("double.nan");
 
-        testNumberConvert!("-real.infinity");
+        /*testNumberConvert!("-real.infinity");
         testNumberConvert!("real.infinity");
         testNumberConvert!("-0.0L");
         testNumberConvert!("0.0L");
         //testNumberConvert!("-real.nan"); //BUG @@@3632@@@
         testNumberConvert!("real.nan");
-
+*/
         /**
             Test min and max values values: min value has an '1' mantissa and minimal exponent,
             Max value has an all '1' bits mantissa and max exponent.
@@ -378,13 +378,13 @@ version(unittest)
         testNumberConvert!("cast(const)3.14");
         testNumberConvert!("cast(immutable)3.14");
 
-        testNumberConvert!("real.min_normal");
+       /* testNumberConvert!("real.min_normal");
         testNumberConvert!("real.max");
         testNumberConvert!("-0.17L");
         testNumberConvert!("3.14L");
         testNumberConvert!("cast(const)3.14L");
         testNumberConvert!("cast(immutable)3.14L");
-
+*/
         /**Test denormalized values*/
 
         /**Max denormalized value, first bit is 1*/
@@ -401,22 +401,22 @@ version(unittest)
         testNumberConvert!("double.min_normal/19");
         testNumberConvert!("double.min_normal/17");
 
-        testNumberConvert!("real.min_normal/2");
+        /*testNumberConvert!("real.min_normal/2");
         testNumberConvert!("real.min_normal/2UL^^63");
         testNumberConvert!("real.min_normal/19");
         testNumberConvert!("real.min_normal/17");
-
+*/
         /**Test imaginary values: convert algorithm is same with real values*/
         testNumberConvert!("0.0Fi");
         testNumberConvert!("0.0i");
-        testNumberConvert!("0.0Li");
+        //testNumberConvert!("0.0Li");
 
         /**True random values*/
-        testNumberConvert!("-0x9.0f7ee55df77618fp-13829L");
+        /*testNumberConvert!("-0x9.0f7ee55df77618fp-13829L");
         testNumberConvert!("0x7.36e6e2640120d28p+8797L");
         testNumberConvert!("-0x1.05df6ce4702ccf8p+15835L");
         testNumberConvert!("0x9.54bb0d88806f714p-7088L");
-
+*/
         testNumberConvert!("-0x9.0f7ee55df7ffp-338");
         testNumberConvert!("0x7.36e6e264012dp+879");
         testNumberConvert!("-0x1.05df6ce4708ep+658");
diff --git a/src/core/internal/hash.d b/src/core/internal/hash.d
index a27def99..b710f4cc 100644
--- a/src/core/internal/hash.d
+++ b/src/core/internal/hash.d
@@ -289,7 +289,7 @@ unittest
     auto h27 = ptrexpr.hashOf();
 
     enum h28 = realexpr.hashOf();
-    enum h29 = raexpr.hashOf();
+    //enum h29 = raexpr.hashOf();
     enum h30 = nullexpr.hashOf();
 
     auto v1 = dexpr;

I thought that might be related to ldc not supporting cross-compiling to the larger 128-bit reals from linux/x64, but I then tried compiling ldc from the ltsmaster branch natively on the tablet and it had the same issue. David, you didn't hit this?

Most of the druntime tests pass with llvm's emulated TLS, only core.thread segfaulted when cross-compiling the tests from ldc master. Several more modules fail when natively compiling ltsmaster, mostly core.sync and the like, indicating TLS issues, though strange that those work when cross-compiling master.

I'm now trying to build the phobos tests, but having issues with compiling std.conv.to. I'll look further into the druntime failures.

@dnadlinger
Copy link
Member Author

Oh, I've hit these, plus varargs are not implement yet.

@egrimley
Copy link

Is the problem really "varargs", or just the calling convention (va_list is a struct that gets passed by value)?

@dnadlinger
Copy link
Member Author

I should have been more precise: The problem isn't the passing of varargs (which works just fine), but the implementation of va_arg in core.stdc.stdarg, where the AAPCS64 ABI needs to be "re-implemented" in D code. (Twice, if you are not clever about it.)

@kinke
Copy link
Member

kinke commented Aug 31, 2017

And fixing #2150 is needed for proper C/C++ interop with somewhat larger structs passed by value.

@dnadlinger
Copy link
Member Author

I've posted a preliminary patch for the ABI issue at #2150, which applies on top of ltsmaster. I'm not sure I'll find the time to test this for a few more days.

@AntonMeep
Copy link

Any updates? I'd like to help with testing on Raspberry Pi 3.

@truedat101
Copy link

@ohdatboi what OS/version are you running on your raspi3? I was surprised to find that raspibian is 32bit os, so by default, most stuff will compile/run just fine there. If you are running something else, ArchLinux or other, would be interesting for testing.

I have a handful of "other" linux/arrch64 platforms that could be used for testing.

@dnadlinger
Copy link
Member Author

I have a handful of "other" linux/arrch64 platforms that could be used for testing.

Thanks, more platforms for testing (especially with different instruction set extensions/…) is always good to have on ARM.

However, the main blocker for steady progress on AArch64 is really just the availability of a CI system. As things are currently, things improve once every while when somebody makes a push, and then slowly regress again. When I worked on AArch64 a while back, most of the test suite passed (with that WIP patch, apart from real formatting and va_arg usage), but the situation is probably quite different right now.

@AntonMeep
Copy link

@truedat101 I use ArchLinux Arm, 32-bit version. Indeed, It works like a charm. Currently, 64-bit systems for RPi3 miss GPU firmware. Somebody works on this for Debian, so eventually it'd be done.

@truedat101
Copy link

@klickverbot are you suggesting the project needs an AARCH64 device for the CI server as a build/test node?

@kinke
Copy link
Member

kinke commented Dec 1, 2017

Yes, running a 64-bit OS and exposed as CI webservice pluggable into GitHub.

@truedat101
Copy link

@kinke - I can provide that. Who should I contact about setup details? I've got a Pine64 cluster I can dedicate for this purpose.

@kinke
Copy link
Member

kinke commented Dec 2, 2017

Oh wow, that'd be awesome. Feel free to drop me a mail at kinke <ät> gmx <döt> net.

@truedat101
Copy link

@kinke sorry got tied up with some CES stuff end of year for work. I'll try to get this box online. I have such a weird setup with my ISP ... hoping DDNS will work.

@joakim-noah
Copy link
Contributor

joakim-noah commented Mar 21, 2018

Alright, finally got back to this and got much farther. With this tiny patch to ldc 1.8 from git master in a linux/x64 VPS to invoke llvm's emulated TLS, I built an ldc against stock llvm that cross-compiles most of the stdlib, after setting CC to the Android NDK's clang and passing -DLDC_TARGET_PRESET=Android-aarch64 to CMake:

diff --git a/driver/codegenerator.cpp b/driver/codegenerator.cpp
index c326ed20..8e4eb554 100644
--- a/driver/codegenerator.cpp
+++ b/driver/codegenerator.cpp
@@ -323,13 +323,13 @@ void CodeGenerator::emit(Module *m) {
     if (global.params.targetTriple->getEnvironment() == llvm::Triple::Android) {
       // On Android, bracket TLS data with the symbols _tlsstart and _tlsend, as
       // done with dmd
-      auto startSymbol = new llvm::GlobalVariable(
+      /*auto startSymbol = new llvm::GlobalVariable(
           ir_->module, llvm::Type::getInt32Ty(ir_->module.getContext()), false,
           llvm::GlobalValue::ExternalLinkage,
           llvm::ConstantInt::get(ir_->module.getContext(), APInt(32, 0)),
           "_tlsstart", &*(ir_->module.global_begin()));
       startSymbol->setSection(".tdata");
-
+*/
       auto endSymbol = new llvm::GlobalVariable(
           ir_->module, llvm::Type::getInt32Ty(ir_->module.getContext()), false,
           llvm::GlobalValue::ExternalLinkage,
diff --git a/driver/targetmachine.cpp b/driver/targetmachine.cpp
index d75a31b2..7f5e6434 100644
--- a/driver/targetmachine.cpp
+++ b/driver/targetmachine.cpp
@@ -457,6 +457,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
   llvm::TargetOptions targetOptions = opts::InitTargetOptionsFromCodeGenFlags();
   if (targetOptions.MCOptions.ABIName.empty())
     targetOptions.MCOptions.ABIName = getABI(triple);
+  targetOptions.EmulatedTLS = 1;

   auto ldcFloatABI = floatABI;
   if (ldcFloatABI == FloatABI::Default) {

I don't have a way to pass llvm's emulated TLS to the GC, so the GC will crap out if called, which is why I disable the GC and a few modules that call it directly when building the druntime-test-runner:

diff --git a/src/test_runner.d b/src/test_runner.d
index cdc7b362..1eb218df 100644
--- a/src/test_runner.d
+++ b/src/test_runner.d
@@ -54,6 +54,8 @@ void doTest(ModuleInfo* moduleInfo, ref UnitTestResult ret)
     if (auto fp = moduleInfo.unitTest)
     {
         auto name = moduleInfo.name;
+	import core.memory; GC.disable;
+if (name != "core.thread" && name != "gc.impl.conservative.gc"){
         ++ret.executed;
         try
         {
@@ -73,6 +75,7 @@ void doTest(ModuleInfo* moduleInfo, ref UnitTestResult ret)
                    cast(uint)name.length, name.ptr,
                    cast(uint)msg.length, msg.ptr);
         }
+}
     }
 }
 

The rest of the tests all pass when running that druntime-test-runner on an Android/AArch64 device, when druntime is patched with my WIP pull for Android/AArch64. I will clean that patch up and put it online later today.

Finally, with a small patch for Phobos, I was able to get the phobos2-test-runner to build and run also:

diff --git a/std/complex.d b/std/complex.d
index 776382292..263295966 100644
--- a/std/complex.d
+++ b/std/complex.d
@@ -853,7 +853,7 @@ Complex!T cos(T)(Complex!T z)  @safe pure nothrow @nogc
     import std.math;
     assert(cos(complex(0.0)) == 1.0);
     assert(cos(complex(1.3L)) == std.math.cos(1.3L));
-    assert(cos(complex(0, 5.2L)) == cosh(5.2L));
+    //assert(cos(complex(0, 5.2L)) == cosh(5.2L));
 }
 
 
diff --git a/std/math.d b/std/math.d
index 788e1c20c..04176b15c 100644
--- a/std/math.d
+++ b/std/math.d
@@ -3270,7 +3270,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return ldexp(cast(real)
         assert(x==-1023);
         assert(ldexp(n, x)==0x1p-1024L);
     }
-    else static assert(false, "Floating point type real not supported");
+    //else static assert(false, "Floating point type real not supported");
 }
 
 /* workaround Issue 14718, float parsing depends on platform strtold
@@ -4009,7 +4009,7 @@ real hypot(real x, real y) @safe pure nothrow @nogc
     static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
 
     // Proves that sqrt(real.max) ~~  0.5/sqrt(real.min_normal)
-    static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+    //static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
 
     real u = fabs(x);
     real v = fabs(y);
@@ -5447,8 +5447,8 @@ public:
             auto oldState = getControlState();
             // If exceptions are not supported, we set the bit but read it back as zero
             // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/fpu/feenablxcpth.c
-            setControlState(oldState | (divByZeroException & EXCEPTION_MASK));
-            bool result = (getControlState() & EXCEPTION_MASK) != 0;
+            setControlState(oldState | (divByZeroException & IeeeFlags.EXCEPTIONS_MASK));
+            bool result = (getControlState() & IeeeFlags.EXCEPTIONS_MASK) != 0;
             setControlState(oldState);
             return result;
         }
diff --git a/std/outbuffer.d b/std/outbuffer.d
index 8a9236f45..f4bf0803e 100644
--- a/std/outbuffer.d
+++ b/std/outbuffer.d
@@ -245,7 +245,7 @@ class OutBuffer
      * Append output of C's vprintf() to internal buffer.
      */
 
-    void vprintf(string format, va_list args) @trusted nothrow
+    /+void vprintf(string format, va_list args) @trusted nothrow
     {
         import core.stdc.stdio : vsnprintf;
         import core.stdc.stdlib : alloca;
@@ -296,7 +296,7 @@ class OutBuffer
         va_start(ap, format);
         vprintf(format, ap);
         va_end(ap);
-    }
+    }+/
 
     /**
      * Formats and writes its arguments in text format to the OutBuffer.
@@ -385,8 +385,8 @@ class OutBuffer
     buf.write("hello");
     buf.write(cast(byte) 0x20);
     buf.write("world");
-    buf.printf(" %d", 62665);
-    assert(cmp(buf.toString(), "hello world 62665") == 0);
+    //buf.printf(" %d", 62665);
+    //assert(cmp(buf.toString(), "hello world 62665") == 0);
 
     buf.clear();
     assert(cmp(buf.toString(), "") == 0);

I also had to apply @jpf91's upstream dlang/phobos@a3d16b958 and dlang/phobos@3a9b0513d, but that's it.

With those patches, including disabling the GC in the test runner as for druntime, only 5 modules assert somewhere in the Phobos tests, std.conv, std.internal.math.{error,gamma}function, std.math, and std.numeric, all likely related to floating-point math. std.file has one test assert on Android 8.0 but not 7.0 or below, because most access to /proc was disabled with Oreo. The std.outbuffer excision is needed because varargs isn't implemented yet.

That marks only 7 Phobos modules that have tests failing on Android/AArch64, everything else passes.

@redstar
Copy link
Member

redstar commented Mar 22, 2018

@joakim-noah Great work!

@joakim-noah
Copy link
Contributor

I've done nothing, other than the simple bindings for Bionic/AArch64 that I've now put online at dlang/druntime#2148. Along with my first patch above to comment out some tests in core.internal.{convert,hash}, that's all I needed to build and run the druntime test runner.

This is all on you, David, Johannes, and whoever else chipped in with the related linux/AArch64 port so far, which I had nothing to do with. Now that I know where the port's at- farther along than the ARM port when I used it for Android- I hope to chip in with finishing it up.

@joakim-noah
Copy link
Contributor

joakim-noah commented Mar 23, 2018

Tried out ltsmaster and the stdlib tests natively on Android/AArch64 again: got everything to build by applying the ldc patch above, commenting out building and running gen_gccbuiltins (which complains about missing some llvm library?), applying a slightly modified version of the druntime pull for Bionic/AArch64 I posted, and for Phobos, applying upstream commit a3d16b9 linked above and commenting out that same first static assert in std.math.

Several more modules fail in Phobos, nine to be exact, along with most of those that failed with ldc master. Most seem related to concurrency, such as std.parallelism and std.process, likely related to the core.sync.* test failures I noted last year.

I don't think any more that that's related to TLS or the GC, as they work when cross-compiled from ldc master. The only core.sync module that changed is core.sync.mutex, so something there likely needs to be backported.

That means 89 of 103 Phobos modules pass though- including the two failing asserts in std.complex and std.outbuffer commented out above- so pretty good overall.

@joakim-noah
Copy link
Contributor

Took a look at the math-related failures that hit modules in both ltsmaster and master, got three of those ltsmaster modules to pass when these workarounds were added or tests disabled, showing there's not much left to be done:

diff --git a/std/conv.d b/std/conv.d
index 628e43c2e..329e89d1b 100644
--- a/std/conv.d
+++ b/std/conv.d
@@ -2975,7 +3055,8 @@ unittest
     assert(s2.empty);
     x = *cast(longdouble *)&ld;
 
-    static if(real.mant_dig == 64)
+    static if (floatTraits!real.realFormat == RealFormat.ieeeExtended ||
+               floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
     {
         version (CRuntime_Microsoft)
             ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
diff --git a/std/math.d b/std/math.d
index d3d70b3e2..664d614c7 100644
--- a/std/math.d
+++ b/std/math.d
@@ -3175,7 +3175,8 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return ldexp(cast(real)
 
 @safe pure nothrow @nogc unittest
 {
-    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
+    static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
+               floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)
     {
         assert(ldexp(1.0L, -16384) == 0x1p-16384L);
         assert(ldexp(1.0L, -16382) == 0x1p-16382L);
@@ -3445,7 +3446,7 @@ real log(real x) @safe pure nothrow @nogc
 }
 
 ///
-@safe pure nothrow @nogc unittest
+version(none) @safe pure nothrow @nogc unittest
 {
     assert(log(E) == 1);
 }
@@ -4501,7 +4502,7 @@ long lrint(real x) @trusted pure nothrow @nogc
 }
 
 ///
-@safe pure nothrow @nogc unittest
+version(none) @safe pure nothrow @nogc unittest
 {
     assert(lrint(4.5) == 4);
     assert(lrint(5.5) == 6);
@@ -4516,7 +4517,7 @@ long lrint(real x) @trusted pure nothrow @nogc
 
 static if (real.mant_dig >= long.sizeof * 8)
 {
-    @safe pure nothrow @nogc unittest
+    version(none) @safe pure nothrow @nogc unittest
     {
         assert(lrint(long.max - 1.5L) == long.max - 1);
         assert(lrint(long.max - 0.5L) == long.max - 1);
@@ -5977,7 +5978,7 @@ int signbit(X)(X x) @nogc @trusted pure nothrow
 {
     debug (math) printf("math.signbit.unittest\n");
     assert(!signbit(float.nan));
-    assert(signbit(-float.nan));
+    //assert(signbit(-float.nan));
     assert(!signbit(168.1234f));
     assert(signbit(-168.1234f));
     assert(!signbit(0.0f));
@@ -5986,7 +5987,7 @@ int signbit(X)(X x) @nogc @trusted pure nothrow
     assert(!signbit(float.max));
 
     assert(!signbit(double.nan));
-    assert(signbit(-double.nan));
+    //assert(signbit(-double.nan));
     assert(!signbit(168.1234));
     assert(signbit(-168.1234));
     assert(!signbit(0.0));
@@ -5995,7 +5996,7 @@ int signbit(X)(X x) @nogc @trusted pure nothrow
     assert(!signbit(double.max));
 
     assert(!signbit(real.nan));
-    assert(signbit(-real.nan));
+    //assert(signbit(-real.nan));
     assert(!signbit(168.1234L));
     assert(signbit(-168.1234L));
     assert(!signbit(0.0L));
diff --git a/std/numeric.d b/std/numeric.d
index 5fb3131b2..0b92b6c2e 100644
--- a/std/numeric.d
+++ b/std/numeric.d
@@ -629,7 +629,7 @@ public:
     }
 }
 
-unittest
+version(none) unittest
 {
     import std.typetuple;
     alias FPTypes =
@@ -665,7 +665,7 @@ unittest
     }
 }
 
-unittest
+version(none) unittest
 {
     import std.conv;
     CustomFloat!(5, 10) y = CustomFloat!(5, 10)(0.125);

I'll pick any low-hanging fruit left with these and move on to emulated TLS.

@joakim-noah
Copy link
Contributor

Kai gave me access to his linux/AArch64 VPS that he uses for his ldc buildbot, so I was able to build and run these same tests there too. Pretty much all the druntime tests for ltsmaster pass, except for the aforementioned tests from core.internal.{convert,hash} and core.thread is super-flaky. The latter hangs or errors out most of the time, but once every 10 runs or so it passes.

After applying upstream commit a3d16b9 to std.conv again, I got the phobos tests to build too. Pretty much the same tests assert as on Android/AArch64, except I didn't have to take out any of the nine segfaulting modules mentioned above because they passed now.

I also ran the dmd test suite and logged only 21 failing tests. 10 errored out because core.stdc.stdarg is unimplemented; 10 because they use the -m32 flag and fail out because Kai's pre-built llvm only compiles in the AArch64 backend and doesn't support 32-bit ARM. The remaining cppabi test module passes if I comment out the testvalist() which tests varags, so it looks like ltsmaster is pretty close to passing the dmd testsuite. 😄

If I build ldc 1.8 natively on linux/AArch64 with that ltsmaster build, it flakes out when building some druntime modules with weird errors, just like when I tried it on Android/AArch64, which I'm guessing are from varargs not working yet. So I built whatever I could and cross-compiled the rest from a linux/x64 VPS, ie some of druntime and most of phobos, as done above for all the stdlib tests with ldc 1.8 for Android. As a result, core.sync.{condition,semaphore} hang, core.thread segfaults, and rt.util.container.treap asserts on the last line.

After applying the std.math and std.outbuffer patches for Phobos pasted above and upstream commits a3d16b9 and 3a9b051, the same seven modules noted for Android fail, plus std.stdio consistently flakes out in a test locking files. This patch gets it down to only three failing modules, std.math and std.internal.math.{error,gamma}function:

diff --git a/std/complex.d b/std/complex.d
index 776382292..8583ca599 100644
--- a/std/complex.d
+++ b/std/complex.d
@@ -853,7 +853,7 @@ Complex!T cos(T)(Complex!T z)  @safe pure nothrow @nogc
     import std.math;
     assert(cos(complex(0.0)) == 1.0);
     assert(cos(complex(1.3L)) == std.math.cos(1.3L));
-    assert(cos(complex(0, 5.2L)) == cosh(5.2L));
+    assert(approxEqual(cos(complex(0, 5.2L)).re, cosh(5.2L), real.epsilon));
 }
 
 
diff --git a/std/conv.d b/std/conv.d
index 6277c3258..714369976 100644
--- a/std/conv.d
+++ b/std/conv.d
@@ -3079,7 +3079,7 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
     assert(parse!double(str).approxEqual(123.456));
 }
 
-@safe unittest
+version(none) @safe unittest
 {
     import std.exception;
     import std.math : isNaN, fabs;
diff --git a/std/numeric.d b/std/numeric.d
index dfd7a0bde..cc441845b 100644
--- a/std/numeric.d
+++ b/std/numeric.d
@@ -614,7 +614,7 @@ public:
     }
 }
 
-@safe unittest
+version(none) @safe unittest
 {
     import std.meta;
     alias FPTypes =
@@ -650,7 +650,7 @@ public:
     }
 }
 
-@system unittest
+version(none) @system unittest
 {
     // @system due to to!string(CustomFloat)
     import std.conv;
@@ -1464,7 +1464,7 @@ do
     T b = ax > bx ? ax : bx;
     // sequence of declarations suitable for SIMD instructions
     T  v = a * cm1 + b * c;
-    assert(isFinite(v));
+    //assert(isFinite(v));
     R fv = f(v);
     if (isNaN(fv) || fv == -T.infinity)
     {
@@ -1585,7 +1585,7 @@ do
     assert(ret.y.approxEqual(0.0));
 }
 
-@safe unittest
+version(none) @safe unittest
 {
     import std.meta : AliasSeq;
     foreach (T; AliasSeq!(double, float, real))
diff --git a/std/stdio.d b/std/stdio.d
index 69be91f9f..f60d1c77f 100644
--- a/std/stdio.d
+++ b/std/stdio.d
@@ -1497,7 +1497,7 @@ Removes the lock over the specified file segment.
         g.unlock();
     }
 
-    version(Posix)
+    version(none)
     @system unittest
     {
         static import std.file;

This same patch, except for the unneeded std.stdio excision, gets it down to those three failing modules with ldc 1.8 cross-compiling for Android/AArch64 too.

@dnadlinger
Copy link
Member Author

Did you build using a LLVM build with assertions enabled? IIRC va_arg isn't even supposed to compile on ARM64/Linux.

@kinke
Copy link
Member

kinke commented Aug 13, 2018

According to the log, it apparently compiles (as long as feeding it primitive types only), but doesn't work. ;) runnable/variadic.d fails here. [And I'm using an LLVM with assertions on my box, that's how I found out about slices/IR structs not being supported.]

@kinke
Copy link
Member

kinke commented Aug 13, 2018

Oh and master still lacks the ExplicitByvalRewrite fix from ltsmaster. One should probably side-by-side diff the whole ltsmaster/master TargetABI stuff (not just AArch64). Plus va_arg doesn't work with master, apparently due to cross-module-inlining stuff added in the meantime (and not supporting D function declarations whose IR declaration is skipped, such as functions with va_arg pragma - not sure this skipping is worth the trouble).

@joakim-noah
Copy link
Contributor

Did you build using a LLVM build with assertions enabled? IIRC va_arg isn't even supposed to compile on ARM64/Linux.

No, I don't, but @myfreeweb did and hit an assertion when he tried to use that pull. Even if va_arg and some math stuff is not working yet, it'll be good to get a mostly working AArch64 build into users' hands.

@JohanEngelen
Copy link
Member

JohanEngelen commented Nov 11, 2018

Not unexpected, as we had similar issues with unoptimized codegen for ARM when we were first porting D there.

I can confirm that for a different piece of software, without -O3 I get really strange behavior of code. With -O0, I get miscompiled code, and adding a line of code suddenly makes the surrounding code work. Will try to reduce to a manageable testcase.

Edit: After a long minimizing session, I found this example. It fails with 1.12, but passes with 1.13-beta1... I don't know which commit fixed this. Perhaps worth tracking it down, so we know it is really fixed. (I don't have the energy now)

class Parser {
    ubyte hunderedforty = 140;

    auto parseModule() {
        auto m = new ubyte;
        bool isModule;
        bool isDeprecatedModule;
        if (currentIs(140) || isDeprecatedModule)
        {
            isModule = true;
        }
        else
        {
            assert(0);  // this assert is triggered with 1.12.0
        }
        ubyte[] declarations;
        return m;
    }

    bool currentIs(ubyte type) const {
        return hunderedforty == type;
    }
}

void main() {
    auto parser = new Parser();
    parser.parseModule();
}

@joakim-noah
Copy link
Contributor

With the given testcase, I'm unable to reproduce with the official ldc 1.2 and 1.3 builds for linux/x64 and Android/AArch64, when compiled with the -O0 or -O3 flags.

@JohanEngelen
Copy link
Member

I was using ubuntu trusty cross-compiling with ldc 1.12 to aarch64, and running the executable in qemu.

@kinke
Copy link
Member

kinke commented Nov 12, 2018

I don't remember exactly, but there might have been some extra issues with bfd for Shippable, and switching to gold improved things. I may be misremembering though, it's been some time.

@leotada
Copy link

leotada commented Jul 2, 2019

Any progress?

@etcimon
Copy link
Contributor

etcimon commented Jan 27, 2020

I have another $2000 USD bounty waiting for PayPal eCheck to pass, aimed at rewarding a full test suite in AArch64 support

@dnadlinger
Copy link
Member Author

I have another $2000 USD bounty waiting for PayPal eCheck to pass, aimed at rewarding a full test suite in AArch64 support

This sound interesting! Would passing it on GNU/Linux be enough, or do you require Android/iOS support?

@etcimon
Copy link
Contributor

etcimon commented Jan 28, 2020

There needs to be a tracking issue for Android/iOS + AArch64 so that I can put a bounty for it separately, but I think this would be a good milestone to just have it working for GNU/Linux.

@valpackett
Copy link
Contributor

Are there any test failures still? It seems already pretty good for real applications. I've been using LDC (mostly on GtkD projects) on FreeBSD/aarch64 for over a year now, haven't noticed any arch specific issues.

@kinke
Copy link
Member

kinke commented Jan 28, 2020

Are there any test failures still?

Yes, mostly related to ABI and lacking core.stdc.stdarg support for C-style varargs, and a few remaining Phobos issues wrt. quadruple precision, i.e., basically the remaining ticks in the initial tracker posting. And the debug runtime libraries seem unusable (possibly related to hanging core.thread.fiber tests?).

Shippable AArch64 CI (on Ubuntu 16.04) is green because test failures are ignored for now; the logs show what's still missing.

@etcimon
Copy link
Contributor

etcimon commented Feb 3, 2020

@kinke
Copy link
Member

kinke commented Feb 16, 2020

@dnadlinger: Are you working on this? I could look into the AArch64 ABI for a start.

@aristotaloss
Copy link

Hey, as an outsider I wanted to hook into this discussion to see where things stand at in terms of stability - is it considered stable enough to use it in commercial development for the Play Store? ARM64 is a requirement as of August iirc due to Google now forcing every APK to have 64 bit natives.

I have no experience with D at all, nor with compiler development, but if there are things I can do to help I'm willing to get my hands dirty!

@kinke
Copy link
Member

kinke commented May 2, 2020

where things stand at in terms of stability - is it considered stable enough to use it in commercial development for the Play Store?

That's difficult to answer. With the upcoming AArch64 ABI fixes (will be in the next beta in a few weeks), I'd think that the compiler side should be pretty complete, leaving the few library issues.

Wrt. Android, the bigger problem is that we have no test results - neither from CI, nor recent ones from a manual run. A full testrun requires testing a native Android LDC on the device, which requires a clang toolchain for linking too, which AFAIK again means that one has to resort to a regular-Linux-emulating app like Termux (edit: for which there's an LDC package I'm 'maintaining' without ever running or testing it myself :])...

@kinke
Copy link
Member

kinke commented May 8, 2020

Update: ABI issues hopefully fixed for good (at least for non-Apple), incl. C(++) interop and varargs.

Current testsuite status for Shippable CI on Ubuntu 16.04:

  • NOTE: all gdb tests are disabled, as they all fail - might be related to the CI setup
  • ldc2-unittest: passes
  • failing lit-tests:
    • dynamiccompile/asm_output.d
    • dynamiccompile/bind_bool.d
    • dynamiccompile/bind_func_opt.d
    • dynamiccompile/bind_nested_opt.d
    • sanitizers/asan_noerror.d
    • sanitizers/fuzz_asan.d
    • sanitizers/fuzz_basic.d
  • dmd-testsuite:
    • debug: passes :)
    • release: fails because the run-dmd-testsuite test driver itself fails to sort the tests (std/algorithm/mutation.d(2796): Swap: lhs internal pointer. - probably related to failing unittest below)
  • failing druntime unittests:
    • core.thread.fiber probably still hangs (only most of the time?) - disabled for CI
  • failing druntime integration tests:
    • druntime-test-profile
    • druntime-test-exceptions
  • failing Phobos unittests:
    • std.math
    • std.format
    • std.algorithm.sorting
    • std.internal.math.gammafunction
    • std.numeric
    • std.concurrency (debug only)

@kinke
Copy link
Member

kinke commented Jun 1, 2020

The dmd-testsuite-release test driver failure is probably a regular Phobos bug and unrelated to AArch64. Also sporadically seen for DMD CI, e.g., there.

@kinke
Copy link
Member

kinke commented Jul 11, 2020

Update: dmd-testsuite-release is now tested and all green, see 36e1911.

@kinke
Copy link
Member

kinke commented Jul 4, 2022

The issue still is, see my latest posts; the bounty less so in the sense of the few remaining parts IMO definitely not justifying the full bounty.

@dnadlinger
Copy link
Member Author

dnadlinger commented Jul 7, 2022

@etcimon: I don't quite remember how Bountysource works (just that I thought they were bought out by some … weird entity at some point), but are you already out of pocket for your generous donation? If no, maybe we should just call it quits; if yes, maybe those of us having done major amounts of work so far can push through to full support and then split the bounty up somehow so that it isn't "lost". (Edit: Also see bountysource/core#1539.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests