Change:
Formating yields incorrect result. I tried this code at a bare metal Raspberry Pi (): writes to the frame buffer using the trait. I expected to see this output: Instead, the output is: I'm using rustc 1.22.0-nightly ( 2017-09-12) with , i.e., is newly built.
Actually, it seems to be a more general problem with the alignment at ARM. In , fails to address the correct bytes within. Since everything was okay a couple of weeks ago, there must be a breaking change in the meantime. I could imagine several places where such change might happened: at the llvm (thus, I would have to update the target description), at the rust compiler, or indeed in the libcore. Could anybody give a hint?
this looks like it'll be pretty difficult for someone else to investigate (difficult to reproduce), do you think you can help narrow down the regression range if possible? All target descriptions are in , although this may or may not be related to that. A more narrow range for the regression would certainly help track this down!
I could narrow it a bit: the change is somewhere around the 10th of September. Version works, does not.
Ok . The only thing that looks even slightly suspect there is , do you know if that'd affect this? Or maybe if there's bug with rvalue promotion?
Rvalue promotion works a lot like regular s, I fail to see a distinction. by "fails to address the correct bytes within .", can you talk about exact addresses? It'd help to see what exact mismatch is occurring. It's possible was put in a different section or was accidentally having a higher alignment.
From the patterns I observed, I would guess that there is an offset of -1. Thus, e.g., instead to address 13... for it comes up with 21... .
If it loads with 2-byte alignment that seems wrong libcore code, since is unaligned. Or is there a minimum alignment on that architecture that we're not respecting?
ARM has a minimum alignment of 2 (unless it is explicitly deactivated).
Ah that seems like something rustc doesn't know about. See - can you try setting that for your target?
We just support for global minimum alignment (), but I'm surprised this hasn't come up before! is this global minimum alignment something we should set for all our ARM targets? Or just the one you're working on?
IHMO llvm cares about alignment, if the target description is correct, especially the data layout. I use Japaric's target description for ARM.
From what we've seen this extra property is not in the data layout.
A wild guess: Could the introduced global minimum alignment be exactly the reason. since it possibly overwrites the architecture's defaults?
It's not in that range though? My change is capable of breaking things that only worked by accident before.
Hi which raspberry pi 1,2 or 3? Could you please paste or link your exact target description?
Oh actually I think I found . Looks like raspi 1. You should also add the feature unless you have set unaligned accesses allowed in SCTLR.
You are right, does the job also for . Kudos!
I'm not entirely clear on whether this is a bug in Rust, so perhaps we can close?
triage: P-high Seems like there is something wrong with (our?) target spec. cc -- what should the target spec be?
Summary: has been using this and running on a bare metal ARMv6 environment (Raspberry Pi). They had to use the option to force LLVM to generate only aligned access to memory. When they didn't they got undefined behavior / the problems described in the issue description. The equivalent target that we support would be . Note that this is for a hosted (Linux) ARMv6 environment. We do not have the option set in our target specs. However, I think this is not a problem because it seems that the Linux kernel enables unaligned accesses (I'm still looking for an official source about this). cf. comments by and below: As for the regression that observed I think that may have been caused by the recent introduction of the "minimum global alignment" option to target specs. My guess is that since target spec does not have that option it's probably now defaulting to 1 whereas before llvm was providing it: it probably was 2. I need to confirm this.
It wouldnt hurt enabling strict-align for arm-unknown-linux-gnueabi(hf), clang does for Armv6 Linux but not for Apple and BSD. I'm not sure if it's strictly required, at least for Linux on the raspi I'm pretty sure it's not. From memory there's some comments in the clang source about but I'm not sure how accurate and up to date they are. I'll try and find a link when I get a minute.
I found in the Linux kernel code -- I don't know how old / valid is though -- and it says that the kernel will (try to) fix unaligned memory access, at some cost, if the bit 1 of is set. The exact text is quoted below: If that bit is set by default on all ARMv6 Linux devices then our current settings won't (or shouldn't) cause crashes. Though there's a performance penalty for having the kernel step in to fix the unaligned memory access. But would it hurt more than having the kernel fix things?
Checking further this can't be the cause of the regression because (1) is not in the reported commit range and (2) if min-global-align is missing in the target spec we'll get the (right) alignment value from LLVM, which is what we have always been doing. So no idea about the regression in the custom target spec.
Sorry I meant to type wouldn't. So I agree we should add it.
Here's the clang comment I was remembering.
The intention of is only to increase alignment, and only for global symbols, not memory access in general. Targets that don't set min-global-align should not see any effect at all.
Checking in from the meeting -- can someone summarize what action on our part is needed, if any? Or is that still undetermined?
I think this just used to work by accident before. Could you please open a PR for fixing the minimum alignment target spec?
There's no bug in rustc here, the bug was in the out of tree target spec that was used. The take away from some of the discussion though is, we should probably add to the in tree Armv6 targets for performance, not correctness, reasons. Do you agree
Yeah, I agree. The Cortex-M target already has that feature enabled for correctness (otherwise programs crash) but all the other ARM Linux targets should see perf improvements. I'd be interested in seeing an after vs before RPi benchmark -- just to get an idea of the perf "penalty" the current targets have.
PR adds +strict-align to all the ARMv6 targets

Discussion:
pub fn target() -> TargetResult { let mut base = super::android_base::opts(); // https://developer.android.com/ndk/guides/abis.html#armeabi <del> base.features = "+v5te".to_string(); </del> <ins> base.features = "+strict-align,+v5te".to_string(); </ins> base.max_atomic_width = Some(64); Ok(Target {

linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { <del> features: "+v6".to_string(), </del> <ins> features: "+strict-align,+v6".to_string(), </ins> abi_blacklist: super::arm_base::abi_blacklist(), .. base },

linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { <del> features: "+v6,+vfp2".to_string(), </del> <ins> features: "+strict-align,+v6,+vfp2".to_string(), </ins> abi_blacklist: super::arm_base::abi_blacklist(), .. base }

// Most of these settings are copied from the arm_unknown_linux_gnueabi // target. <del> base.features = "+v6".to_string(); </del> <ins> base.features = "+strict-align,+v6".to_string(); </ins> base.max_atomic_width = Some(64); Ok(Target { // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it

// Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. <del> base.features = "+v6,+vfp2".to_string(); </del> <ins> base.features = "+strict-align,+v6,+vfp2".to_string(); </ins> base.max_atomic_width = Some(64); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM