Open AnnikaCodes opened 3 years ago
OK, I did some more testing and found that it crashes with the following return types:
u128
i128
u64
, i64
, or f64
Option<T>
where T
= u64
, i64
, or f64
Here's a minimal example:
#![no_std]
#![feature(no_core, lang_items)]
#![no_core]
#[lang = "sized"]
pub trait Sized {}
fn llvm_test() -> (u64, bool) {
(24234324, false)
}
The m68k backend is in an early stage, so some issues are to be expected.
If it's a LLVM issue, please file a bug in the LLVM upstream tracker against the M68k backend.
CC @ricky26 @mshockwave @jrtc27
I will check if the bug is present in upstream LLVM and file a bug if indicated, thanks!
Those all look like cases where the ABI returns values indirectly (the usual thing on 32-bit architectures, where 64-bit values are returned in register pairs, but larger things indirectly), so the frontend should be adding an implicit sret argument to the function and representing it as returning void, with the backends always assuming that part of the ABI has been done correctly. What IR do you get for your example?
This is the IR I get:
*** IR Dump Before Module Verifier (verify) ***
; Function Attrs: nonlazybind uwtable
define { i64, i8 } @llvm_test() unnamed_addr #0 !dbg !6 {
start:
%0 = alloca { i64, i8 }, align 4
%1 = bitcast { i64, i8 }* %0 to i64*, !dbg !18
store i64 24234324, i64* %1, align 4, !dbg !18
%2 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 1, !dbg !18
store i8 0, i8* %2, align 4, !dbg !18
%3 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 0, !dbg !19
%4 = load i64, i64* %3, align 4, !dbg !19
%5 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 1, !dbg !19
%6 = load i8, i8* %5, align 4, !dbg !19, !range !20
%7 = trunc i8 %6 to i1, !dbg !19
%8 = zext i1 %7 to i8, !dbg !19
%9 = insertvalue { i64, i8 } undef, i64 %4, 0, !dbg !19
%10 = insertvalue { i64, i8 } %9, i8 %8, 1, !dbg !19
ret { i64, i8 } %10, !dbg !19
}
Yep, rustc frontend bug, should be:
; Function Attrs: nonlazybind uwtable
define void @llvm_test({ i64, i8 }* sret %result) unnamed_addr #0 !dbg !6 {
start:
%0 = alloca { i64, i8 }, align 4
%1 = bitcast { i64, i8 }* %0 to i64*, !dbg !18
store i64 24234324, i64* %1, align 4, !dbg !18
%2 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 1, !dbg !18
store i8 0, i8* %2, align 4, !dbg !18
%3 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 0, !dbg !19
%4 = load i64, i64* %3, align 4, !dbg !19
%5 = getelementptr inbounds { i64, i8 }, { i64, i8 }* %0, i32 0, i32 1, !dbg !19
%6 = load i8, i8* %5, align 4, !dbg !19, !range !20
%7 = trunc i8 %6 to i1, !dbg !19
%8 = zext i1 %7 to i8, !dbg !19
%9 = insertvalue { i64, i8 } undef, i64 %4, 0, !dbg !19
%10 = insertvalue { i64, i8 } %9, i8 %8, 1, !dbg !19
store { i64, i8 } %10, { i64, i8 }* %result
ret void
}
Alright, thanks for the example of correct IR; I'll see if I can figure out how to fix this in rustc.
OK, I've been working on fixes for this, but I haven't figured out a way to test anything since rustc won't build because of another LLVM error, which seems to be related to the left shift operator when used on 64bit integers:
LLVM ERROR: Cannot select: 0x7fb0c9876678: i32,i32 = shl_parts 0x7fb0c98788e0, Constant:i32<0>, 0x7fb0c9876540
0x7fb0c98788e0: i32,ch = CopyFromReg 0x7fb0c621bf58, Register:i32 %0
0x7fb0c98769b8: i32 = Register %0
0x7fb0c9877170: i32 = Constant<0>
0x7fb0c9876540: i32 = add nuw nsw 0x7fb0c9878670, Constant:i32<21>
0x7fb0c9878670: i32 = AssertZext 0x7fb0c9876af0, ValueType:ch:i8
0x7fb0c9876af0: i32,ch = CopyFromReg 0x7fb0c621bf58, Register:i32 %2
0x7fb0c9876a88: i32 = Register %2
0x7fb0c9878a80: i32 = Constant<21>
In function: _ZN17compiler_builtins5float4conv11__floatsidf17hb63047be181dca88E
This is happening in the __floatsidf
function in compiler-builtins, which calls int_to_float
which does indeed do left shifting.
@AnnikaCodes Thanks a lot for investigating this and thanks a lot to @jrtc27 for figuring out so quickly what the problem is!
The left-shift on 64-bit ints crash is an LLVM bug (it can be reproduced in C); I've reported it to the LLVM project.
Bug has been fixed in LLVM https://github.com/llvm/llvm-project/issues/51461.
@AnnikaCodes If you use LLVM from git and libc with the patches from here https://github.com/rust-lang/libc/pull/2680 and here https://github.com/rust-lang/libc/commit/7a027d34c2d748b23a81fb75c9b84242fe70fcda, you should be able to work on this issue.
If I understood correctly, you already have a potential fix for this issue?
Those all look like cases where the ABI returns values indirectly (the usual thing on 32-bit architectures, where 64-bit values are returned in register pairs, but larger things indirectly), so the frontend should be adding an implicit sret argument to the function and representing it as returning void, with the backends always assuming that part of the ABI has been done correctly. What IR do you get for your example?
Isn't that what ret.make_indirect();
should be doing for us?
@glaubitz I believe the problem here is that rust only uses target-specific ABI adjustment when using C (or other foreign) ABI, but not for Rust ABI.
I assume that for other targets, LLVM will handle this gracefully even if it does not match the platform C ABI.
@glaubitz I believe the problem here is that rust only uses target-specific ABI adjustment when using C (or other foreign) ABI, but not for Rust ABI.
I assume that for other targets, LLVM will handle this gracefully even if it does not match the platform C ABI.
Thanks for the explanation. I have to admit that I currently have no idea how to fix this issue. I tried playing with variations in the ABI code for m68k in Rust a bit to modify the function return behavior but that didn't make any difference.
I need to set up my Rust development environment again; I think I know how to fix this based on jrtc's IR, but I was never able to test it so no promises there :)
@nikic
@glaubitz I believe the problem here is that rust only uses target-specific ABI adjustment when using C (or other foreign) ABI, but not for Rust ABI.
I assume that for other targets, LLVM will handle this gracefully even if it does not match the platform C ABI.
Can you give me a hint where the Rust code is located that generates the return code?
@glaubitz See https://github.com/rust-lang/rust/blob/f90b06d7fb00470177516c5881bcec0432cb4f24/compiler/rustc_middle/src/ty/layout.rs#L3177. Note that adjust_for_foreign_abi is only called for non-Rust ABI.
Possibly a target option could be added to always use the C ABI for a target, if LLVM doesn't support non-C ABI for it.
Possibly a target option could be added to always use the C ABI for a target, if LLVM doesn't support non-C ABI for it.
Ah, that somewhat rings a bell. I think I've heard that before that one had to enforce the C-ABI for a target. Now I just need to remember where ;).
I have tried this hack now and it seems to fix the issue for me:
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6d4178c3e75..1fd875c1b7a 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -3223,6 +3223,15 @@ fn fn_abi_adjust_for_abi(
return;
}
+
+ Abi::ScalarPair { .. }
+ if self.tcx.sess.target.arch == "m68k" =>
+ {
+ arg.make_indirect();
+ return;
+ }
+
+
_ => return,
}
It just fails with a different error now which could be due to the lacks of support for atomic operations in the M68k LLVM backend:
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> m68k-unknown-linux-gnu)
Compiling core v0.0.0 (/data/home/glaubitz/rust-m68k/library/core)
Compiling rustc-std-workspace-core v1.99.0 (/data/home/glaubitz/rust-m68k/library/rustc-std-workspace-core)
Compiling compiler_builtins v0.1.69
Compiling libc v0.2.118
rustc: /data/home/glaubitz/llvm-project/llvm/lib/IR/Constants.cpp:2016: static llvm::Constant* llvm::ConstantExpr::getCast(unsigned int, llvm::Constant*, llvm::Type*, bool): Assertion `CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"' failed.
rustc exited with signal: 6 (core dumped)
error: could not compile `core`
Caused by:
process didn't exit successfully: `/data/home/glaubitz/rust-m68k/build/bootstrap/debug/rustc --crate-name core --edition=2021 library/core/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C debuginfo=0 -C metadata=283e6e00a9b48510 -C extra-filename=-283e6e00a9b48510 --out-dir /data/home/glaubitz/rust-m68k/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps --target m68k-unknown-linux-gnu -C linker=cc -L dependency=/data/home/glaubitz/rust-m68k/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps -L dependency=/data/home/glaubitz/rust-m68k/build/x86_64-unknown-linux-gnu/stage1-std/release/deps -Csymbol-mangling-version=legacy -Zunstable-options -Zmacro-backtrace -Clink-args=-Wl,-z,origin '-Clink-args=-Wl,-rpath,$ORIGIN/../lib' -Cprefer-dynamic -Cembed-bitcode=yes '-Zcrate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/")' -Z binary-dep-depinfo` (exit status: 254)
warning: build failed, waiting for other jobs to finish...
LLVM ERROR: Cannot select: t6: ch = AtomicStore<(store unordered (s16) into %ir.9)> t3:1, t5, t3
t5: i32,ch = CopyFromReg t0, Register:i32 %1
t4: i32 = Register %1
t3: i16,ch = AtomicLoad<(load unordered (s16) from %ir.10)> t0, t2
t2: i32,ch = CopyFromReg t0, Register:i32 %2
t1: i32 = Register %2
In function: __llvm_memcpy_element_unordered_atomic_2
error: build failed
Build completed unsuccessfully in 0:00:17
See this related LLVM bug: https://github.com/llvm/llvm-project/issues/48236.
I have been looking at the corresponding Rust code in layout.rs
and I have to admit that I don't fully understand the following code:
if abi == SpecAbi::Rust
|| abi == SpecAbi::RustCall
|| abi == SpecAbi::RustIntrinsic
|| abi == SpecAbi::PlatformIntrinsic
{
let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| {
if arg.is_ignore() {
return;
}
match arg.layout.abi {
Abi::Aggregate { .. } => {}
// This is a fun case! The gist of what this is doing is
// that we want callers and callees to always agree on the
// ABI of how they pass SIMD arguments. If we were to *not*
// make these arguments indirect then they'd be immediates
// in LLVM, which means that they'd used whatever the
// appropriate ABI is for the callee and the caller. That
// means, for example, if the caller doesn't have AVX
// enabled but the callee does, then passing an AVX argument
// across this boundary would cause corrupt data to show up.
//
// This problem is fixed by unconditionally passing SIMD
// arguments through memory between callers and callees
// which should get them all to agree on ABI regardless of
// target feature sets. Some more information about this
// issue can be found in #44367.
//
// Note that the platform intrinsic ABI is exempt here as
// that's how we connect up to LLVM and it's unstable
// anyway, we control all calls to it in libstd.
Abi::Vector { .. }
if abi != SpecAbi::PlatformIntrinsic
&& self.tcx.sess.target.simd_types_indirect =>
{
arg.make_indirect();
return;
}
_ => return,
}
// Pass and return structures up to 2 pointers in size by value, matching `ScalarPair`.
// LLVM will usually pass these in 2 registers, which is more efficient than by-ref.
let max_by_val_size = Pointer.size(self) * 2;
let size = arg.layout.size;
if arg.layout.is_unsized() || size > max_by_val_size {
arg.make_indirect();
} else {
// We want to pass small aggregates as immediates, but using
// a LLVM aggregate type for this leads to bad optimizations,
// so we pick an appropriately sized integer type instead.
arg.cast_to(Reg { kind: RegKind::Integer, size });
}
};
fixup(&mut fn_abi.ret);
for arg in &mut fn_abi.args {
fixup(arg);
}
} else {
fn_abi.adjust_for_foreign_abi(self, abi)?;
}
If I read the code correctly, the code will never get beyond the match
statement if arg.layout.abi
equals Abi::ScalarPair
and thus the fix-up starting at let max_by_val_size = Pointer.size(self) * 2;
will never be executed for the ScalarPair
type.
Can someone with more Rust knowledge explain the code?
The code applies to aggregates and sometimes vectors. Scalars and pairs don't (currently) need any fixing up. I imagine the m68k backend needs to be altered to permit pairs as arguments and return values, but I could see an argument to be made that, if the ABI doesn't let you pass pairs in registers, that should be the frontend's responsibility to lower.
Ah, that actually makes sense and that explains why my hack above fixes the issue.
Do you still want me to work on this?
Abi::ScalarPair { .. } + if self.tcx.sess.target.arch == "m68k" => + { + arg.make_indirect(); + return; + }
I'm not able to compile the following with your diff:
pub struct Struct {
a: i64,
b: i32,
}
fn t() -> Struct {
Struct { a: 1000, b: 3000 }
}
The following error is produced:
Called function is not the same type as the call!
%3 = call i32 @_ZN6simple5start17h171a72bdff8bf80aE(void ()* @_ZN6simple4main17h40225ebee735581cE, i32 %0, i8** %1)
in function main
LLVM ERROR: Broken function found, compilation aborted!
I'm not sure why this is; here is the produced LLVM IR with your diff:
; simple::t
; Function Attrs: nonlazybind uwtable
define internal void @_ZN6simple1t17h9b9464898cd4c360E({ i64, i32 }* noalias nocapture noundef sret({ i64, i32 }) dereferenceable(12) %0) unnamed_addr #0 {
start:
%1 = bitcast { i64, i32 }* %0 to i64*
store i64 1000, i64* %1, align 4
%2 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %0, i32 0, i32 1
store i32 3000, i32* %2, align 4
ret void
}
and the IR from compiling a similar function in C with clang
:
%struct.Struct = type { i64, i32, [4 x i8] }
; Function Attrs: noinline nounwind optnone
define dso_local void @t(%struct.Struct* noalias sret(%struct.Struct) align 8 %0) #0 {
%2 = getelementptr inbounds %struct.Struct, %struct.Struct* %0, i32 0, i32 0
store i64 1000, i64* %2, align 8
%3 = getelementptr inbounds %struct.Struct, %struct.Struct* %0, i32 0, i32 1
store i32 3000, i32* %3, align 8
ret void
}
The IR you pasted is for a totally different function
Yes, it's for the following in C:
struct Struct {
long long a;
int b;
};
struct Struct t() {
struct Struct j;
j.a = 1000;
j.b = 3000;
return j;
}
The error you got was for the following instruction:
%3 = call i32 @_ZN6simple5start17h171a72bdff8bf80aE(void ()* @_ZN6simple4main17h40225ebee735581cE, i32 %0, i8** %1)
The Rust-produced IR you included is for _ZN6simple1t17h9b9464898cd4c360E
, which neither is _ZN6simple5start17h171a72bdff8bf80aE
nor contains a call to _ZN6simple5start17h171a72bdff8bf80aE
. Therefore it is not relevant.
Abi::ScalarPair { .. } + if self.tcx.sess.target.arch == "m68k" => + { + arg.make_indirect(); + return; + }
I'm not able to compile the following with your diff:
For me the change made the error go away when building a host compiler for m68k. However, I ended up running into another problem which is a result of the lack of support for atomics in the LLVM M68k backend, see: https://github.com/llvm/llvm-project/issues/48236
I think this is related. My code doesn't have returns, but maybe build-std
is causing it to crash?
I tried this code:
#![no_std]
#![feature(no_core, lang_items)]
#![no_core]
#[lang = "sized"]
pub trait Sized {}
fn llvm_test() -> ! {
}
>cargo build -Zbuild-std --target m68k-unknown-linux-gnu
Compiling compiler_builtins v0.1.79
Compiling core v0.0.0 (/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core)
Compiling libc v0.2.131
Compiling cc v1.0.73
Compiling memchr v2.5.0
Compiling std v0.0.0 (/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std)
Compiling unwind v0.0.0 (/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/unwind)
Compiling rustc-std-workspace-core v1.99.0 (/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/rustc-std-workspace-core)
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x27babd3)[0x7fe8cff2cbd3]
/usr/lib/libc.so.6(+0x38a40)[0x7fe8cd418a40]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm12SelectionDAG7getNodeEjRKNS_5SDLocENS_3EVTENS_7SDValueENS_11SDNodeFlagsE+0x46)[0x7fe8cb0a2f86]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(+0x2a835fc)[0x7fe8caadc5fc]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZNK4llvm14TargetLowering11LowerCallToERNS0_16CallLoweringInfoE+0x125a)[0x7fe8cab7a3ea]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm19SelectionDAGBuilder11LowerCallToERKNS_8CallBaseENS_7SDValueEbbPKNS_10BasicBlockE+0x96e)[0x7fe8cab04d8e]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm19SelectionDAGBuilder9visitCallERKNS_8CallInstE+0x2ad)[0x7fe8caabeddd]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm16SelectionDAGISel20SelectAllBasicBlocksERKNS_8FunctionE+0xfdb)[0x7fe8caabadab]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE+0x376)[0x7fe8caef9136]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE+0x890)[0x7fe8cb2c3990]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE+0x2f)[0x7fe8cb2c2f6f]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x224)[0x7fe8cb2c2774]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2297c55)[0x7fe8cfa09c55]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x22975a9)[0x7fe8cfa095a9]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x229545a)[0x7fe8cfa0745a]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2276a34)[0x7fe8cf9e8a34]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2275863)[0x7fe8cf9e7863]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x22396e0)[0x7fe8cf9ab6e0]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-4393e7d07259b8a4.so(rust_metadata_std_e55f2e3b0b26feec+0xfd8b3)[0x7fe8cd6ed8b3]
/usr/lib/libc.so.6(+0x8678d)[0x7fe8cd46678d]
/usr/lib/libc.so.6(__clone+0x44)[0x7fe8cd4e78e4]
Compiling alloc v0.0.0 (/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc)
Compiling cfg-if v0.1.10
Compiling adler v0.2.3
LLVM ERROR: unable to allocate function return #2
error: could not compile `compiler_builtins`
warning: build failed, waiting for other jobs to finish...
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x27babd3)[0x7f01ded34bd3]
/usr/lib/libc.so.6(+0x38a40)[0x7f01dc220a40]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(+0x2f5a626)[0x7f01d9dbb626]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm16SelectionDAGISel17CodeGenAndEmitDAGEv+0x144c)[0x7f01d98eebcc]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm16SelectionDAGISel20SelectAllBasicBlocksERKNS_8FunctionE+0x13b6)[0x7f01d98c3186]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE+0x376)[0x7f01d9d01136]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE+0x890)[0x7f01da0cb990]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE+0x2f)[0x7f01da0caf6f]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libLLVM-15-rust-1.65.0-nightly.so(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x224)[0x7f01da0ca774]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2297c55)[0x7f01de811c55]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x22975a9)[0x7f01de8115a9]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x229545a)[0x7f01de80f45a]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2276a34)[0x7f01de7f0a34]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x2275863)[0x7f01de7ef863]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-f10772d81e144ae7.so(+0x22396e0)[0x7f01de7b36e0]
/home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-4393e7d07259b8a4.so(rust_metadata_std_e55f2e3b0b26feec+0xfd8b3)[0x7f01dc4f58b3]
/usr/lib/libc.so.6(+0x8678d)[0x7f01dc26e78d]
/usr/lib/libc.so.6(__clone+0x44)[0x7f01dc2ef8e4]
LLVM ERROR: unable to allocate function return #2
error: could not compile `libc`
error: could not compile `adler`
Caused by:
process didn't exit successfully: `rustc --crate-name adler /home/wcampbell/.cargo/registry/src/github.com-1ecc6299db9ec823/adler-0.2.3/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --cfg 'feature="compiler_builtins"' --cfg 'feature="core"' --cfg 'feature="rustc-dep-of-std"' -C metadata=0ab7c7911269cebb -C extra-filename=-0ab7c7911269cebb --out-dir /home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps --target m68k-unknown-linux-gnu -Z force-unstable-if-unmarked -L dependency=/home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps -L dependency=/home/wcampbell/projects/wcampbell/code/m68k/target/debug/deps --extern compiler_builtins=/home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps/libcompiler_builtins-fb1f862333bf4539.rmeta --extern core=/home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps/librustc_std_workspace_core-0320986fdb3fa22c.rmeta --cap-lints allow` (signal: 11, SIGSEGV: invalid memory reference)
error: could not compile `core`
Caused by:
process didn't exit successfully: `rustc --crate-name core --edition=2021 /home/wcampbell/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=4cf3f75b36268316 -C extra-filename=-4cf3f75b36268316 --out-dir /home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps --target m68k-unknown-linux-gnu -Z force-unstable-if-unmarked -L dependency=/home/wcampbell/projects/wcampbell/code/m68k/target/m68k-unknown-linux-gnu/debug/deps -L dependency=/home/wcampbell/projects/wcampbell/code/m68k/target/debug/deps --cap-lints allow` (signal: 11, SIGSEGV: invalid memory reference)
rustc --version --verbose
:
rustc 1.65.0-nightly (015a824f2 2022-08-22)
binary: rustc
commit-hash: 015a824f2dffe32707fceb59c47effaf7b73486c
commit-date: 2022-08-22
host: x86_64-unknown-linux-gnu
release: 1.65.0-nightly
LLVM version: 15.0.0
@glaubitz Not sure if you're still working on this, but, is M68K still buildable? I've applied the patch from above on the latest main and it gets further in the build as expected (but tweaked as the paths have changed), but then fails with:
Compiling rustc-demangle v0.1.21
Invalid bitcast
ptr bitcast (i32 57 to ptr)
in function _ZN77_$LT$adler..algo..U32X4$u20$as$u20$core..ops..arith..RemAssign$LT$u32$GT$$GT$10rem_assign17hd75aa07212cc3b0eE
LLVM ERROR: Broken function found, compilation aborted!
error: could not compile `adler`
warning: build failed, waiting for other jobs to finish...
Invalid bitcast
ptr bitcast (i32 25 to ptr)
in function _ZN49_$LT$u8$u20$as$u20$core..num..bignum..FullOps$GT$12full_div_rem17he267c3f90789e7feE
LLVM ERROR: Broken function found, compilation aborted!
error: could not compile `core`
LLVM ERROR: unable to allocate function return #2
error: could not compile `compiler_builtins`
Which seems different than the original issue. I'm not seeing anything custom in Rust, so seems more like an LLVM bug? Both errors are on the modulus operator.
EDIT: Relevant IR for function:
; <adler::algo::U32X4 as core::ops::arith::RemAssign<u32>>::rem_assign
; Function Attrs: nonlazybind uwtable
define void @"_ZN77_$LT$adler..algo..U32X4$u20$as$u20$core..ops..arith..RemAssign$LT$u32$GT$$GT$10rem_assign17hd75aa07212cc3b0eE"(ptr noalias noundef align 2 dereferenceable(16) %self, i32 %quotient) unnamed_addr #0 {
start:
%_14 = icmp eq i32 %quotient, 0
br i1 %_14, label %panic, label %bb3.preheader, !prof !7
bb3.preheader: ; preds = %start
%0 = load i32, ptr %self, align 2
%1 = urem i32 %0, %quotient
store i32 %1, ptr %self, align 2
%iter.sroa.0.0.ptr = getelementptr inbounds i32, ptr %self, i32 1
%2 = load i32, ptr %iter.sroa.0.0.ptr, align 2
%3 = urem i32 %2, %quotient
store i32 %3, ptr %iter.sroa.0.0.ptr, align 2
%iter.sroa.0.0.ptr.1 = getelementptr inbounds i32, ptr %self, i32 2
%4 = load i32, ptr %iter.sroa.0.0.ptr.1, align 2
%5 = urem i32 %4, %quotient
store i32 %5, ptr %iter.sroa.0.0.ptr.1, align 2
%iter.sroa.0.0.ptr.2 = getelementptr inbounds i32, ptr %self, i32 3
%6 = load i32, ptr %iter.sroa.0.0.ptr.2, align 2
%7 = urem i32 %6, %quotient
store i32 %7, ptr %iter.sroa.0.0.ptr.2, align 2
ret void
panic: ; preds = %start
; call core::panicking::panic
tail call void @_ZN4core9panicking5panic17h185473536b5a7e7eE(ptr noalias nocapture noundef nonnull dereferenceable(8) @str.0, ptr noalias noundef readonly align 2 dereferenceable(16) bitcast (i32 57 to ptr)) #7
unreachable
}
@dawn-minion The M68k backend in LLVM is still considered experimental and there are still a number of bugs.
I recommend that you always try to build the Rust compiler with LLVM from git since there are regularly coming new improvements in for the M68k backend.
FWIW, we have both a Patreon and an OpenCollective campaign to support the developers of the M68k LLVM backend, so if you're really interested in getting the backend working, please consider supporting either of the campaigns.
Applying the ScalarPair
change, compiling core
seems to current fail at:
rustc: /home/ian/src/rust/src/llvm-project/llvm/lib/IR/Constants.cpp:1978: static llvm::Constant llvm::ConstantExpr::getCast(unsigned int, llvm::Constant, llvm::Type*, bool): Assertion `CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"' failed.
Trying with RUSTFLAGS='-C codegen-units=1' RUSTC_LOG=rustc_codegen_llvm=debug
:
...
DEBUG rustc_codegen_llvm::builder call (ptr:; Function Attrs: nocallback nofree nosync nounwind nonlazybind willreturn memory(none)
declare i1 @llvm.expect.i1(i1, i1) #13
) with args ([(i1: %30 = extractvalue { i32, i1 } %28, 1, !dbg !36), (i1:i1 false)])
DEBUG rustc_codegen_llvm::declare get_declared_value(name="str.0")
DEBUG rustc_codegen_llvm::declare declare_global(name="str.0")
DEBUG rustc_codegen_llvm::callee get_fn(instance=Instance { def: Item(WithOptConstParam { did: DefId(0:8235 ~ core[3c2c]::panicking::panic), const_param_did: None }), substs: [] })
DEBUG rustc_codegen_llvm::builder call (ptr:; Function Attrs: cold noinline noreturn nonlazybind uwtable
declare void @_ZN4core9panicking5panic17h79a06827901c0983E(ptr, ptr align 2) unnamed_addr #6
) with args ([(ptr:@str.0 = internal constant [28 x i8] c"attempt to add with overflow"), (i32:i32 28), (ptr:@1 = private unnamed_addr constant <{ ptr, [12 x i8] }> <{ ptr @0, [12 x i8] c"\00\00\00i\00\00\02\D4\00\00\00\0D" }>, align 2)])
DEBUG rustc_codegen_llvm::builder type mismatch in function call of (ptr:; Function Attrs: cold noinline noreturn nonlazybind uwtable
declare void @_ZN4core9panicking5panic17h79a06827901c0983E(ptr, ptr align 2) unnamed_addr #6
). Expected ptr for param 1, got i32; injecting bitcast
rustc: /home/ian/src/rust/src/llvm-project/llvm/lib/IR/Constants.cpp:1978: static llvm::Constant* llvm::ConstantExpr::getCast(unsigned int, llvm::Constant*, llvm::Type*, bool): Assertion `CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"' failed.
error: could not compile `core` (lib)
I think the issue here is simply that M68kTargetLowering
doesn't override CanLowerReturn
, so it tries to lower the return value to a register even when there aren't any left, and fails an assertion? In which case, this is easy to fix copying a few lines from another backend. I guess I'll submit that as a patch to LLVM once I write a regression test to go with it.
Then I seem to get the error with _ZN17compiler_builtins3mem31memcpy_element_unordered_atomic17h79aaf71609b14d3fE
.
Is that one supposed to have been fixed now that https://github.com/llvm/llvm-project/issues/48236 is closed?
I think the issue here is simply that
M68kTargetLowering
doesn't overrideCanLowerReturn
, so it tries to lower the return value to a register even when there aren't any left, and fails an assertion? In which case, this is easy to fix copying a few lines from another backend. I guess I'll submit that as a patch to LLVM once I write a regression test to go with it.
Sounds good. Thanks for catching this. Looking forward for your patch!
Then I seem to get the error with
_ZN17compiler_builtins3mem31memcpy_element_unordered_atomic17h79aaf71609b14d3fE
.Is that one supposed to have been fixed now that llvm/llvm-project#48236 is closed?
Yes, support for atomic operations were recently implemented and there are also already patches for TLS support.
I have used the following change now and it works for me:
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index 0ee3a07e15f4..7e6cb46406e8 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -1058,6 +1058,15 @@ SDValue M68kTargetLowering::LowerFormalArguments(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
+
+bool M68kTargetLowering::CanLowerReturn(
+ CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
+ SmallVector<CCValAssign, 16> RVLocs;
+ CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
+ return CCInfo.CheckReturn(Outs, RetCC_M68k);
+}
+
SDValue
M68kTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CCID,
bool IsVarArg,
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h
index f9037e7ff497..d43160fe48d2 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.h
+++ b/llvm/lib/Target/M68k/M68kISelLowering.h
@@ -257,6 +257,11 @@ private:
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ LLVMContext &Context) const override;
+
/// Lower the result values of a call into the
/// appropriate copies out of appropriate physical registers.
SDValue LowerReturn(SDValue Chain, CallingConv::ID CCID, bool IsVarArg,
@ids1024 Do you want to post the patch yourself or shall I?
Furthermore, in order to use atomics, we will have to raise the baseline to M68020:
diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
index ebd74012dcd..9bcd56bed00 100644
--- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
@@ -3,6 +3,7 @@
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
+ base.cpu = "M68020".into();
base.max_atomic_width = Some(32);
Target {
I will open a PR for that.
I submitted a patch once I figured out how to add a test for it in LLVM IR: https://reviews.llvm.org/D148856
Ah, so it needs to target the M68020 for atomics? https://www.debian.org/ports/m68k says it requires a 68020, so this probably isn't an issue for the Linux target. But presumably it should be possible to compile libcore for a base 68000. I guess if it doesn't have atomic operations that would use max_atomic_width = None
.
With the change to base.cpu = "M68020".into()
I'm getting:
RTD is not implemented
UNREACHABLE executed at /home/ian/src/llvm-project/llvm/lib/Target/M68k/M68kExpandPseudo.cpp:255!
With the change to
base.cpu = "M68020".into()
I'm getting:RTD is not implemented UNREACHABLE executed at /home/ian/src/llvm-project/llvm/lib/Target/M68k/M68kExpandPseudo.cpp:255!
Edit: llvm/llvm-project#60554
Yes, this is expected because RTD
is not implemented yet as the linked issue explains. It's an optimization for return from a function and you can just temporarily disable it with:
diff --git a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
index 5383d3107955..8ecd5724354d 100644
--- a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
+++ b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
@@ -251,9 +251,9 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MIB = BuildMI(MBB, MBBI, DL, TII->get(M68k::RTS));
} else if (isUInt<16>(StackAdj)) {
- if (STI->atLeastM68020()) {
- llvm_unreachable("RTD is not implemented");
- } else {
+ // if (STI->atLeastM68020()) {
+ // llvm_unreachable("RTD is not implemented");
+ // } else {
// Copy PC from stack to a free address(A0 or A1) register
// TODO check if pseudo expand uses free address register
BuildMI(MBB, MBBI, DL, TII->get(M68k::MOV32aj), M68k::A1)
@@ -269,7 +269,7 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
// RTS
BuildMI(MBB, MBBI, DL, TII->get(M68k::RTS));
- }
+ // }
} else {
// TODO: RTD can only handle immediates as big as 2**16-1.
// If we need to pop off bytes before the return address, we
We can either implement RTD
for 68020+ or add an option -mno-rtd
similar to GCC.
Ah, so it needs to target the M68020 for atomics? https://www.debian.org/ports/m68k says it requires a 68020, so this probably isn't an issue for the Linux target. But presumably it should be possible to compile libcore for a base 68000. I guess if it doesn't have atomic operations that would use
max_atomic_width = None
.
FWIW, we can introduce a new target for this case similar to the various none
targets that the Rust compiler supports. These are all nostd
targets if I understand correctly.
Since this fix has now landed in LLVM, I guess we can close this issue.
@AnnikaCodes Could you close this issue?
With https://reviews.llvm.org/D149034 and previous patches, using base.cpu = "M68010".into()
, I'm able to compile libcore with a few hacks in LLVM:
/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 78ac0c27d720..f4e0b10d3349 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -508,7 +508,7 @@ `(SDNode *N, unsigned &NestLevel, unsigned &MaxNest,
BestMaxNest = MyMaxNest;
}
}
- assert(Best);
+ //assert(Best);
MaxNest = BestMaxNest;
return Best;
}
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index c37ec304bf19..465c39d9cf13 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -75,9 +75,9 @@ M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM,
setOperationAction(ISD::MUL, MVT::i8, Promote);
setOperationAction(ISD::MUL, MVT::i16, Legal);
- if (Subtarget.atLeastM68020())
- setOperationAction(ISD::MUL, MVT::i32, Legal);
- else
+ //if (Subtarget.atLeastM68020())
+ // setOperationAction(ISD::MUL, MVT::i32, Legal);
+ //else
setOperationAction(ISD::MUL, MVT::i32, LibCall);
setOperationAction(ISD::MUL, MVT::i64, LibCall);
@@ -183,6 +183,12 @@ M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM,
ISD::ATOMIC_SWAP,
},
{MVT::i8, MVT::i16, MVT::i32}, LibCall);
+ setOperationAction(
+ {
+ ISD::ATOMIC_LOAD,
+ ISD::ATOMIC_STORE,
+ },
+ {MVT::i8, MVT::i16, MVT::i32}, Expand);
setMinFunctionAlignment(Align(2));
}
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 15b97ba25af4..fe597389dc7a 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -672,12 +672,12 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool ToSR = DstReg == M68k::SR;
if (FromCCR) {
- assert(M68k::DR8RegClass.contains(DstReg) &&
- "Need DR8 register to copy CCR");
+ //assert(M68k::DR8RegClass.contains(DstReg) &&
+ // "Need DR8 register to copy CCR");
Opc = M68k::MOV8dc;
} else if (ToCCR) {
- assert(M68k::DR8RegClass.contains(SrcReg) &&
- "Need DR8 register to copy CCR");
+ //assert(M68k::DR8RegClass.contains(SrcReg) &&
+ // "Need DR8 register to copy CCR");
Opc = M68k::MOV8cd;
} else if (FromSR || ToSR)
llvm_unreachable("Cannot emit SR copy instruction");
The ATOMIC_LOAD
/ATOMIC_STORE
change might be correct. Obviously removing the assert in FindCallSeqStart
is wrong; I'm having trouble understanding the CALLSEQ_START
/CALLSEQ_END
stuff, and how to fix that. And it should be possible to compile libcore targeting the 68000 or 68020, not just 68010. But this at least narrows down what the remaining issues here are...
Or well, the mul
change here isn't needed targeting the 68010. For the 68020, that doesn't seem to be working correctly in instruction selection, there's the RTD is not implemented
error, and I still ran into something else, I believe.
With https://reviews.llvm.org/D149034 and previous patches, using
base.cpu = "M68010".into()
, I'm able to compile libcore with a few hacks in LLVM:/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 78ac0c27d720..f4e0b10d3349 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -508,7 +508,7 @@ `(SDNode *N, unsigned &NestLevel, unsigned &MaxNest, BestMaxNest = MyMaxNest; } } - assert(Best); + //assert(Best); MaxNest = BestMaxNest; return Best; }
I think this is likely caused by this issue: https://discourse.llvm.org/t/finding-the-start-sdnode-of-a-call-sequence/62806
I have a few ideas on how to fix it and will probably start to work on this issue recently.
With https://reviews.llvm.org/D149034 and previous patches, using
base.cpu = "M68010".into()
, I'm able to compile libcore with a few hacks in LLVM: (...)
We're at the point now, any idea how to move forward?
https://reviews.llvm.org/D152120 addressed the multiply issue, so that's another of the workarounds from this diff rendered unnecessary.
I don't really understand the SelectionDAG issue. Not sure if @mshockwave has made any progress solving that one? That seems to be the most complicated thing here.
The ATOMIC_LOAD
/ATOMIC_STORE
change here may be correct, in which case that can just be submitted to LLVM. But I've been meaning to research more about how this part works and see if there are other things that need a fix like that before submitting a patch.
I've tried to investigate the FromCCR
/ToCCR
issue a bit, but I still don't understand exactly how that works. May be a simple fix for anyone that does.
After that, libcore should compile. And I think there were one or two other small issue with libstd. Then it would be possible to test actual applications like ripgrep.
The FromCCR
/ToCCR
asserts seem like they might just be wrong; the documentation I'm aware of says that MOVE from CCR and MOVE to CCR are word operations but only change the low-order byte anyway.
Sadly it's not just the asserts, at least for the M68000. I'm trying to build libcore for the M68000 with the patches outlined in this thread and if I remove the asserts from FromCCR/ToCCR
I get another error:
rustc-LLVM ERROR: Attempting to emit MOV16dc instruction but the Feature_AtLeastM68010 predicate(s) are not met
Which makes sense because the instruction it's trying to emit was only added with the 68010. There is even a FIXME in the llvm code at that place. I sadly don't really know how to fix it or what the alternatives are for the M68000
rumor has it that @knickish has managed to build libcore with the upstream LLVM.
Oh, I think only after patching: https://github.com/llvm/llvm-project/pull/114714
Core should build with current upstream main, but asserts have to be off. Oncelock has a method that hits that assert, but the actual assembly should be ok for it regardless as the selected instruction hasn't changed even with the patch you mentioned
I think the m68k support for Rust is really interesting, and I've been trying to make a project with it. However, I'm unable to build the core library, which makes it really hard to actually use Rust.
You can replicate this by running
cargo build -Zbuild-std=core --target m68k-unknown-linux-gnu
.I expected it to build successfully.
Instead, I get an LLVM error:
I think this has something to do with functions that return
u64
andu128
?Meta
rustc --version --verbose
:Backtrace
``` Compiling core v0.0.0 (/Users/annika/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core) Compiling rustc-std-workspace-core v1.99.0 (/Users/annika/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/rustc-std-workspace-core) error: could not compile `core` Caused by: process didn't exit successfully: `rustc --crate-name core --edition=2018 /Users/annika/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=803798926cf71182 -C extra-filename=-803798926cf71182 --out-dir /Users/annika/randbats-winrates/target/m68k-unknown-linux-gnu/debug/deps --target m68k-unknown-linux-gnu -Z force-unstable-if-unmarked -L dependency=/Users/annika/randbats-winrates/target/m68k-unknown-linux-gnu/debug/deps -L dependency=/Users/annika/randbats-winrates/target/debug/deps --cap-lints allow` (signal: 11, SIGSEGV: invalid memory reference) warning: build failed, waiting for other jobs to finish... error: build failed ```