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

1.18.0 armv7 regression: extern-fn-struct-passing-abi assertion failed, passed in 1.17.0 #43329

Closed
infinity0 opened this issue Jul 19, 2017 · 17 comments
Assignees
Labels
C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@infinity0
Copy link
Contributor

Same errors on both Debian and Fedora:

failures:

---- [run-make] run-make/extern-fn-struct-passing-abi stdout ----
[..]
thread 'main' panicked at 'assertion failed: `(left == right)` (left: `FloatPoint { x: 0, y: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000341032099879 }`, right: `FloatPoint { x: 5, y: -3 }`)', test.rs:115

The corresponding test succeeded in 1.17 on Debian, though it appears Fedora did not run this test (and ran fewer tests overall) for 1.17 and earlier.

cc @cuviper

@arielb1 arielb1 added I-nominated regression-from-stable-to-stable Performance or correctness regression from one stable version to another. labels Jul 19, 2017
@sanxiyn
Copy link
Member

sanxiyn commented Jul 20, 2017

Can you try with -Z fuel=test=0? This will let us know if it is due to field reordering new in 1.18.

@sanxiyn sanxiyn added the O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state label Jul 20, 2017
@infinity0
Copy link
Contributor Author

I added this flag to src/test/run-make/extern-fn-struct-passing-abi/Makefile, I get an extra message optimization-fuel-exhausted: Reorder fields of "Rect" in the output of compiletest, but the same assertion failure still occurs.

I didn't recompile rustc itself with the flag that you mentioned, however. Did you want me to try that too?

@sanxiyn
Copy link
Member

sanxiyn commented Jul 20, 2017

Hm, no. I think you just proved this is not due to field reordering.

@parched
Copy link
Contributor

parched commented Jul 21, 2017

Those tests look like they are only for x86, so I wonder why they are being run now on arm.

@parched
Copy link
Contributor

parched commented Jul 21, 2017

Oh actually, looking more closely they are just commented for x86 but should always be valid.

@cuviper
Copy link
Member

cuviper commented Jul 21, 2017

There was only one commit touching librustc_trans/cabi_arm.rs between 1.17 and 1.18, f0636b6 from #40658, but that was almost a complete rewrite. Maybe nightlies before and after that merge can help confirm if that's the regression.

@cuviper
Copy link
Member

cuviper commented Jul 21, 2017

The corresponding test succeeded in 1.17

This FloatPoint part of this test wasn't added until 0303a33, after 1.17. Using the current test sources with older stable compilers, I can reproduce the same failure back to 1.14. 1.13 had known codegen issues with armhf. In 1.12, it hits test.c:290: float_point: Assertion `p.x == 5.' failed.

Anyway, it seems this is not strictly a regression, but rather something that never worked, just wasn't tested until FloatPoint was added to the test in 1.18.

@eddyb, since you added that, any idea what could be missing on ARM?

@eddyb
Copy link
Member

eddyb commented Jul 21, 2017

The only way to really know is to read the clang source.

@cuviper
Copy link
Member

cuviper commented Jul 22, 2017

Looking at disassembly, the C side is expecting the struct FloatPoint parameter in VFP registers d0 and d1, and is returning the same. The Rust side is passing the arg in general r0/etc registers and a memory address for it to return to.

The ARM Procedure Call Standard 6.1.2.1 describes the homogeneous aggregate conditions for using VFP, and I found where clang checks for that. We're also already doing this for AArch64 per #24181.

I'll work on adding this for ARM hf targets.

@eddyb
Copy link
Member

eddyb commented Jul 22, 2017

Ah, missing homogenous aggregates would explain it, and adding support for it is fine as long as there is no old version it would break for.

@cuviper
Copy link
Member

cuviper commented Jul 24, 2017

What's the right way for cabi_arm.rs to know whether it is compiling for a VFP ABI?
In clang, ARMABIInfo has enum ABIKind for this.

@eddyb
Copy link
Member

eddyb commented Jul 24, 2017

cc @alexcrichton @michaelwoerister for #43329 (comment) - I don't think we have a way to tell, other than by matching on the target triple or something. Maybe there's a target feature?

@alexcrichton
Copy link
Member

AFAIK it's related to the target today, but I'll admit that my knowledge of VFP and ARM things is tenuous at best. My understand though is that:

  • arm-unknown-linux-gnueabi - not VFP
  • arm-unknown-linux-gnueabihf - VFP
  • armv7-unknown-linux-gnueabihf - VFP

In that, I think "hf" at the end of the target indicates VFP which I'm taking as transitively implying "hard float"

@cuviper
Copy link
Member

cuviper commented Jul 25, 2017

Shouldn't it be on a per-function basis? What if someone used extern "aapcs"?

LLVM has three ARM-specific CallingConv values:

    /// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
    /// but still used on some targets).
    ARM_APCS = 66,

    /// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
    /// convention (aka EABI). Soft float variant.
    ARM_AAPCS = 67,

    /// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
    ARM_AAPCS_VFP = 68,

AFAICS Rust only explicitly sets ARM_AAPCS, internally ArmAapcsCallConv, but I believe the default "C" calling convention for hard-float targets will be ARM_AAPCS_VFP. We probably should have an explicit extern "aapcs-vfp" too.

cc @TimNN and @japaric, as I know you two have dealt with ARM ABIs in the past...

@parched
Copy link
Contributor

parched commented Jul 25, 2017

@alexcrichton @cuviper Yeah that's right, if it's extern "C" then it's based on the environment part of the LLVM triple. So basically if it ends in "hf" then it's aapcs-vfp otherwise it's aapcs. I guess extern "aapcs-vfp" will get added when someone needs it, extern "aapcs" was added for the compiler builtins because some functions are extern "aapcs" regardless of the target environment.

@cuviper
Copy link
Member

cuviper commented Jul 25, 2017

OK, so for now it's roughly target_triple.ends_with("hf") && !func.is_explicitly_aapcs() -- now I'll figure out how to actually code that. :)

@Mark-Simulacrum Mark-Simulacrum added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 27, 2017
@nikomatsakis
Copy link
Contributor

Compiler team meeting: Assigning to @eddyb since I can't assign @cuviper, but @eddyb thinks @cuviper is working on it. =)

triage: P-high -- I-wrong on P1 target.

@rust-highfive rust-highfive added P-high High priority and removed I-nominated labels Jul 27, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 28, 2017
cuviper added a commit to cuviper/rust that referenced this issue Jul 28, 2017
Hard-float ARM targets use the AACPS-VFP ABI, which passes and returns
homogeneous float/vector aggregates in the VFP registers.

Fixes rust-lang#43329.
@sanxiyn sanxiyn removed the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label Jul 28, 2017
bors added a commit that referenced this issue Jul 29, 2017
Support homogeneous aggregates for hard-float ARM

Hard-float ARM targets use the AAPCS-VFP ABI, which passes and returns
homogeneous float/vector aggregates in the VFP registers.

Fixes #43329.

r? @eddyb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state P-high High priority 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

10 participants