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

Trying to use MSA instructions on MIPS segfaults LLVM #46310

Closed
gnzlbg opened this issue Nov 27, 2017 · 7 comments
Closed

Trying to use MSA instructions on MIPS segfaults LLVM #46310

gnzlbg opened this issue Nov 27, 2017 · 7 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. O-MIPS Target: MIPS processors T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Nov 27, 2017

I am trying to set up the MIPS SIMD intrinsics in stdsimd and am running into the following segfault:

#![feature(repr_simd, simd_ffi, link_llvm_intrinsics)]

#[allow(non_camel_case_types)]
#[repr(simd)]
pub struct i8x16(
    i8, i8, i8, i8, i8, i8, i8, i8, 
    i8, i8, i8, i8, i8, i8, i8, i8
);

#[allow(improper_ctypes)]
extern "C" {
    #[link_name = "llvm.mips.add.a.b"]
    fn msa_add_a_b(a: i8x16, b: i8x16) -> i8x16;
}

pub fn foo(a: i8x16) -> i8x16 {  // FAILS
// switch line above with this like and it works:
// pub fn foo() -> i8x16 {
    let b = i8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    unsafe { msa_add_a_b(a, b) }
}

I have tried this example on clang and it appears to work just fine. The only thing clang does is enabling the target feature msa (here they call AddTargetFeature, which is defined here).

The segfault is:

* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x28)
  * frame #0: 0x00000001023954fc librustc_llvm-a2329f2cbc39342e.dylib`getCopyFromParts(llvm::SelectionDAG&, llvm::SDLoc const&, llvm::SDValue const*, unsigned int, llvm::MVT, llvm::EVT, llvm::Value const*, llvm::Optional<llvm::ISD::NodeType>) + 1740
    frame #1: 0x00000001023ce39f librustc_llvm-a2329f2cbc39342e.dylib`llvm::SelectionDAGISel::LowerArguments(llvm::Function const&) + 5935
    frame #2: 0x000000010241ba2b librustc_llvm-a2329f2cbc39342e.dylib`llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 3467
    frame #3: 0x000000010241a212 librustc_llvm-a2329f2cbc39342e.dylib`llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1426
    frame #4: 0x0000000101ab93b0 librustc_llvm-a2329f2cbc39342e.dylib`llvm::MipsDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 32
    frame #5: 0x0000000101ae1e40 librustc_llvm-a2329f2cbc39342e.dylib`llvm::MipsSEDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 32
    frame #6: 0x00000001025ddbb6 librustc_llvm-a2329f2cbc39342e.dylib`llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 134
    frame #7: 0x0000000102d43ee2 librustc_llvm-a2329f2cbc39342e.dylib`llvm::FPPassManager::runOnFunction(llvm::Function&) + 514
    frame #8: 0x0000000102d440e3 librustc_llvm-a2329f2cbc39342e.dylib`llvm::FPPassManager::runOnModule(llvm::Module&) + 51
    frame #9: 0x0000000102d44564 librustc_llvm-a2329f2cbc39342e.dylib`llvm::legacy::PassManagerImpl::run(llvm::Module&) + 900
    frame #10: 0x00000001016ca069 librustc_llvm-a2329f2cbc39342e.dylib`LLVMRustWriteOutputFile + 377
    frame #11: 0x0000000100ae65c2 librustc_trans-7aa3e893b33f5b2f.dylib`rustc_trans::back::write::write_output_file::hd049294080e3f948 + 82
    frame #12: 0x0000000100b1265d librustc_trans-7aa3e893b33f5b2f.dylib`rustc_trans::back::write::codegen::_$u7b$$u7b$closure$u7d$$u7d$::h91658a3b1acaa0c8 (.llvm.303723C2) + 1101
    frame #13: 0x0000000100b0e5d1 librustc_trans-7aa3e893b33f5b2f.dylib`rustc::util::common::time::hd7baa9c382938e50 + 81
    frame #14: 0x0000000100ae866c librustc_trans-7aa3e893b33f5b2f.dylib`rustc_trans::back::write::codegen::hc049fe7d136f626c (.llvm.7E0FE580) + 2892
    frame #15: 0x0000000100ade258 librustc_trans-7aa3e893b33f5b2f.dylib`std::sys_common::backtrace::__rust_begin_short_backtrace::hacfaa5a113f25a93 + 6216
    frame #16: 0x0000000100adf83e librustc_trans-7aa3e893b33f5b2f.dylib`std::panicking::try::do_call::hee7d7a49ebd6d159 (.llvm.7E0FE580) + 46
    frame #17: 0x00000001061b7ccf libstd-44e67c1a5c665082.dylib`__rust_maybe_catch_panic + 31
    frame #18: 0x0000000100ae4b24 librustc_trans-7aa3e893b33f5b2f.dylib`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hdd902711ad474596 (.llvm.7E0FE580) + 180
    frame #19: 0x00000001061a8dcc libstd-44e67c1a5c665082.dylib`std::sys::imp::thread::Thread::new::thread_start::h6774aae010e52aa5 + 140
    frame #20: 0x00007fff6dacf6c1 libsystem_pthread.dylib`_pthread_body + 340
    frame #21: 0x00007fff6dacf56d libsystem_pthread.dylib`_pthread_start + 377
    frame #22: 0x00007fff6dacec5d libsystem_pthread.dylib`thread_start + 13
@alexcrichton
Copy link
Member

You may want to use a build with llvm assertions enabled, it's probably hitting an assert first somewhere

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Nov 27, 2017

And now I wish that we had alternate builds for all targets 😆

@TimNN TimNN added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. O-MIPS Target: MIPS processors labels Nov 28, 2017
@XAMPPRocky XAMPPRocky added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Feb 19, 2018
@jcowgill
Copy link
Contributor

jcowgill commented Mar 7, 2018

I just tried this with mips64el on Rust nightly and it seems to work.

$ build/mips64el-unknown-linux-gnuabi64/stage2/bin/rustc -O -C target-feature=+msa --crate-type rlib --emit asm msa.rs
$ cat msa.s
[...]
_ZN3msa3foo17ha775519a7ac61b9eE:
[...]
        ld.b    $w0, 0($5)
        ldi.b   $w1, 0
        add_a.b $w0, $w0, $w1
        st.b    $w0, 0($4)
        jr      $ra
        move    $2, $4

If you omit the -C target-feature=+msa then LLVM gets angry, but I'm not sure if that's a bug.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 7, 2018

Could you try without -C target-feature=+msa but marking foo with #[target_feature(enable = "msa")] ? If that works then I'll add some msa intrinsics and mips build bots to stdsimd so that those interested can start adding intrinsics for it.

@jcowgill
Copy link
Contributor

jcowgill commented Mar 7, 2018

Yeah this works:

#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, target_feature)]

#[allow(non_camel_case_types)]
#[repr(simd)]
pub struct i8x16(
    i8, i8, i8, i8, i8, i8, i8, i8,
    i8, i8, i8, i8, i8, i8, i8, i8
);

#[allow(improper_ctypes)]
extern "C" {
    #[link_name = "llvm.mips.add.a.b"]
    fn msa_add_a_b(a: i8x16, b: i8x16) -> i8x16;
}

#[target_feature(enable = "msa")]
pub unsafe fn foo(a: i8x16) -> i8x16 {
    let b = i8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    msa_add_a_b(a, b)
}

I have a feeling it will only work on 64-bit at the moment though because MSA is not compatible with the default floating point mode on 32-bit (FP32). I think enabling "FPXX" will make it work, but I haven't tested it yet.

@jcowgill
Copy link
Contributor

jcowgill commented Mar 7, 2018

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 7, 2018

I am currently trying with the mips64el target and it does seem to work. I am going to close this issue, it was filled two LLVM versions ago and now it doesn't segfaults anymore. @jcowgill I'll ping you in the stdsimd PR so that you can take a look.

@gnzlbg gnzlbg closed this as completed Mar 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. O-MIPS Target: MIPS processors T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants