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

GHA: Experiment with native arm64 DMD build on macos-14 #17035

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

kinke
Copy link
Contributor

@kinke kinke commented Oct 28, 2024

No description provided.

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @kinke! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#17035"

thewilsonator
thewilsonator previously approved these changes Oct 28, 2024
@kinke
Copy link
Contributor Author

kinke commented Oct 28, 2024

The macos-14 GHA runners are ARM64 ones, so using Rosetta emulation all the way. And that seems to be uber-slow for the DMD testsuite (maybe because spawning a lot of compile & link processes?).

It might be worth a try to use an LDC host compiler for that job, and building/using an ARM64 DMD (which obviously still generates x86_64 code). Edit: Oh, no dmd.root.longdouble.longdouble_soft support when building DMD for a non-x86 architecture.

@kinke kinke force-pushed the gha_bump_macos branch 4 times, most recently from c368a6c to e7b262e Compare October 29, 2024 22:10
@kinke kinke force-pushed the gha_bump_macos branch 2 times, most recently from 1ca35cb to c1fa370 Compare March 15, 2025 23:30
@kinke kinke force-pushed the gha_bump_macos branch 2 times, most recently from 82a0489 to 20be77e Compare March 16, 2025 01:59
@kinke kinke changed the title GHA: Bump macOS images to 13 and 14 GHA: Experiment with native arm64 DMD build on macos-14 Mar 16, 2025
os: macos-13
host_dmd: dmd
- job_name: macOS 14 arm64, LDC
os: macos-14
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macos-14 onwards are native M1 runners. These macOS arm64 runners offer a builtin x86_64 emulator - as opposed to the Linux AArch64 GitHub Actions runners. This means we can still generate x86_64 code and run it directly on these runners.

host_dmd: dmd
- job_name: macOS 14 arm64, LDC
os: macos-14
host_dmd: ldc
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching the host D compiler to LDC on these macOS arm64 runners means that a native arm64 LDC build is used, generating arm64 binaries. So the fresh DMD is built as a native arm64 executable - but still defaults to generating x86_64 code.

[Using a DMD host compiler yields a fresh x86_64 DMD build, which then passes all tests on the arm64 box. In that case, both the host compiler and the fresh DMD need to run in the Rosetta 2 emulator, as both are x86_64 executables.]

extern(C) int main() { puts("Hello world from native arm64!"); return 0; }
EOF

generated/osx/release/64/dmd -betterC -arm -run hello.d
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be the very first CI test of DMD compiling & linking a native arm64 executable. It currently fails to link; AFAICT, because the Mach-O object file still specifies the x86_64 architecture, although it contains arm64 code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to implement the trivial Mach-O header changes; now the linker complains about an invalid relocation:

ld: relocation at '_main'+0x0008 is not supported: r_address=0x8, r_type=1, r_extern=0, r_pcrel=1, r_length=2 in '/Users/runner/work/dmd/dmd/hello.o'

I'm not going down that rabbit hole. ;)

- name: Test dmd
if: success() || failure()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[continue if the arm64 smoke test step failed]

sudo ln -s $candidateDir/make /usr/local/bin/make
break
fi
done
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[the location of GNU make is different for the arm64 macOS runners (vs. x86_64 macos-13 runners)]

@@ -742,7 +742,7 @@ ubyte loadconst(elem* e, int im)
// Note that for this purpose, -0 is not regarded as +0,
// since FLDZ loads a +0
assert(sz <= zeros.length);
zero = (memcmp(p, zeros.ptr, sz) == 0);
zero = (memcmp(p, zeros.ptr, sz < targ_ldouble.sizeof ? sz : targ_ldouble.sizeof) == 0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows one of the current problems for cross-compiling with DMD - it currently assumes the target real is the same as the host real_t (targ_ldouble in the backend).

Any native arm64 DMD build will never be able to use a hardware x87 real_t (and dmd.root.longdouble.longdouble_soft is based on x87 asm, so needs an x86_64 host). The general AArch64 ABI specifies 128-bit quadruple precision for long double, but Apple and Microsoft both opted for double precision.

So this means that the native macOS arm64 DMD build here for CI uses a double-precision real_t for representing compile-time reals. This means that real.max actually overflows to infinity when cross-compiling to x86_64 etc., because the compiler cannot represent the target value.

LDC has the same basic problem/limitation, mentioning this in https://wiki.dlang.org/Cross-compiling_with_LDC#Limitations. GDC uses a software real_t type.

Wrt. DMD, there might easily be more locations in the backend with assumptions that targ_ldouble matches the target real format. I was actually surprised the native arm64 build doesn't seem to crash for the testsuite. :) But the number of test failures is, I think, much higher than expected from a pure compile-time-real-is-less-precise-than-target-real issue.

@kinke
Copy link
Contributor Author

kinke commented Mar 16, 2025

@WalterBright: These are some first steps towards arm64 CI for DMD.

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

Successfully merging this pull request may close these issues.

3 participants