Rust: Fix stack probing for x32

Created on 3 Apr 2019  路  11Comments  路  Source: rust-lang/rust

I've got a Rust minimal repro code (a.rs), its mir output (a.mir), its x86 codegen output (a.x86.ll) and its gnu-x32 codegen output (a.gnux32.ll) All these files are in this this gist.

Currently, llc a.gnux32.ll fails, saying "llvm error cannot emit physreg copy instruction".
I don't understand llvm ir at all myself, but i tried commenting out L309, L311 & L314 out (all accessing a special 'variable?' called 'unsized_tmp') and llc it passes, then i uncomment L309 and llc fails again.

This issue is blocking #59500. Maybe @eddyb, @oli-obk or someone else who's familiar with rust/src/librustc_codegen_ssa/mir/operand.rs could have a look or give me a hint about this?

A-LLVM C-bug O-x32 T-compiler

Most helpful comment

All 11 comments

Forgot to mention: I generated these files with -C panic=abort to make the files shorter, but that's unimportant detail, i guess.

If you haven't yet, you might try using bugpoint to minimize the ll to a smaller reproducer.

Using bugpoint, i got this(I used llvm-dis to convert it to text):

; ModuleID = 'bugpoint-reduced-simplified.bc'
source_filename = "b.7rcbfp3g-cgu.0"
target datalayout = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnux32"

define dso_local void @_ZN1b7call_it17h422679d04fa7b4d4E() unnamed_addr #0 {
start:
  %unsized_tmp = alloca i8, i32 undef, align 16
  unreachable
}

attributes #0 = { "probe-stack"="__rust_probestack" }

!llvm.module.flags = !{!0}

!0 = !{i32 7, !"PIE Level", i32 2}

Looks like it can't deal with the "probe-stack" attribute: removing that makes it work. My guess is the probe stack code doesn't do well with gnux32 targets which is 64bit but has 32bit pointers.

The LLVM debug log re: why it fails:

********** EXPANDING POST-RA PSEUDO INSTRS **********
********** Function: _ZN1b7call_it17h422679d04fa7b4d4E
real copy:   $rax = COPY killed renamable $eax
Cannot copy EAX to RAX
LLVM ERROR: Cannot emit physreg copy instruction

Speaking of stack probing, I guess @Zoxc might know more about this?

To unblock things, I think it is reasonable to delete base.stack_probes = true; line in src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs file while we investigate the issue. Stack probes are x86-only feature that is disabled on other architectures anyway.

I guess LLVM needs a upstream fix for stack probing on x32 (it probably emits code using 64-bit registers). We may also want a x32 specific stack probe function in https://github.com/rust-lang-nursery/compiler-builtins/blob/master/src/probestack.rs.

I've pushed #59686 as the temporary workaround.

Fixed upstream by https://github.com/llvm/llvm-project/commit/b75c8fc6fbac57e0bde233516fa125f65b36af84. I believe a separate stack probing function for x32 is not necessary, the one for x86_64 should work fine.

The LLVM fix is now in nightly, so we can try re-enabling this again.

Was this page helpful?
0 / 5 - 0 ratings