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

ARMv5 needs +strict-align #42314

Merged
merged 1 commit into from
Jun 1, 2017
Merged

ARMv5 needs +strict-align #42314

merged 1 commit into from
Jun 1, 2017

Conversation

jannic
Copy link
Contributor

@jannic jannic commented May 30, 2017

Without that flag, LLVM generates unaligned memory access instructions, which are not allowed on ARMv5.

For example, the 'hello world' example from cargo --new failed with:

$ ./hello
Hello, world!
thread 'main' panicked at 'assertion failed: end <= len', src/libcollections/vec.rs:1113
note: Run with `RUST_BACKTRACE=1` for a backtrace.

I traced this error back to the following assembler code in BufWriter::flush_buf:

    6f44:       e28d0018        add     r0, sp, #24
[...]
    6f54:       e280b005        add     fp, r0, #5
[...]
    7018:       e5cd001c        strb    r0, [sp, #28]
    701c:       e1a0082a        lsr     r0, sl, #16
    7020:       03a01001        moveq   r1, #1
    7024:       e5cb0002        strb    r0, [fp, #2]
    7028:       e1cba0b0        strh    sl, [fp]

Note that fp points to sp + 29, so the three str*-instructions should fill up a 32bit - value at sp + 28, which is later used as the value n in Ok(n) => written += n. This doesn't work on ARMv5 as the strh can't write to the unaligned contents of fp, so the upper bits of n won't get cleared, leading to the assertion failure in Vec::drain.

With +strict-align, the code works as expected.

Without that flag, LLVM generates unaligned memory access instructions, which are not allowed on ARMv5.

For example, the 'hello world' example from `cargo --new` failed with:
```
$ ./hello
Hello, world!
thread 'main' panicked at 'assertion failed: end <= len', src/libcollections/vec.rs:1113
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

I traced this error back to the following assembler code in `BufWriter::flush_buf`:
```
    6f44:       e28d0018        add     r0, sp, rust-lang#24
[...]
    6f54:       e280b005        add     fp, r0, rust-lang#5
[...]
    7018:       e5cd001c        strb    r0, [sp, rust-lang#28]
    701c:       e1a0082a        lsr     r0, sl, rust-lang#16
    7020:       03a01001        moveq   r1, rust-lang#1
    7024:       e5cb0002        strb    r0, [fp, rust-lang#2]
    7028:       e1cba0b0        strh    sl, [fp]
```

Note that `fp` points to `sp + 29`, so the three `str*`-instructions should fill up a 32bit - value at `sp + 28`, which is later used as the value `n` in `Ok(n) => written += n`. This doesn't work on ARMv5 as the `strh` can't write to the unaligned contents of `fp`, so the upper bits of `n` won't get cleared, leading to the assertion failure in Vec::drain.

With `+strict-align`, the code works as expected.
@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@eddyb
Copy link
Member

eddyb commented May 30, 2017

r? @japaric

@rust-highfive rust-highfive assigned japaric and unassigned eddyb May 30, 2017
@japaric
Copy link
Member

japaric commented May 30, 2017

Thanks, @jannic. That makes sense. The thumbv6m-none-eabi needed the same treatment. Makes me wonder why LLVM is not setting that option by default for these subarchitectures.

@bors r+

@bors
Copy link
Contributor

bors commented May 30, 2017

📌 Commit 4450807 has been approved by japaric

@jannic
Copy link
Contributor Author

jannic commented May 30, 2017

According to rust-lang/llvm@4fb2f33, "clang is now responsible for setting strict-align". The same is probably true for rustc.

@aidanhs aidanhs added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jun 1, 2017
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Jun 1, 2017
ARMv5 needs +strict-align

Without that flag, LLVM generates unaligned memory access instructions, which are not allowed on ARMv5.

For example, the 'hello world' example from `cargo --new` failed with:
```
$ ./hello
Hello, world!
thread 'main' panicked at 'assertion failed: end <= len', src/libcollections/vec.rs:1113
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

I traced this error back to the following assembler code in `BufWriter::flush_buf`:
```
    6f44:       e28d0018        add     r0, sp, rust-lang#24
[...]
    6f54:       e280b005        add     fp, r0, rust-lang#5
[...]
    7018:       e5cd001c        strb    r0, [sp, rust-lang#28]
    701c:       e1a0082a        lsr     r0, sl, rust-lang#16
    7020:       03a01001        moveq   r1, #1
    7024:       e5cb0002        strb    r0, [fp, rust-lang#2]
    7028:       e1cba0b0        strh    sl, [fp]
```

Note that `fp` points to `sp + 29`, so the three `str*`-instructions should fill up a 32bit - value at `sp + 28`, which is later used as the value `n` in `Ok(n) => written += n`. This doesn't work on ARMv5 as the `strh` can't write to the unaligned contents of `fp`, so the upper bits of `n` won't get cleared, leading to the assertion failure in Vec::drain.

With `+strict-align`, the code works as expected.
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Jun 1, 2017
ARMv5 needs +strict-align

Without that flag, LLVM generates unaligned memory access instructions, which are not allowed on ARMv5.

For example, the 'hello world' example from `cargo --new` failed with:
```
$ ./hello
Hello, world!
thread 'main' panicked at 'assertion failed: end <= len', src/libcollections/vec.rs:1113
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

I traced this error back to the following assembler code in `BufWriter::flush_buf`:
```
    6f44:       e28d0018        add     r0, sp, rust-lang#24
[...]
    6f54:       e280b005        add     fp, r0, rust-lang#5
[...]
    7018:       e5cd001c        strb    r0, [sp, rust-lang#28]
    701c:       e1a0082a        lsr     r0, sl, rust-lang#16
    7020:       03a01001        moveq   r1, #1
    7024:       e5cb0002        strb    r0, [fp, rust-lang#2]
    7028:       e1cba0b0        strh    sl, [fp]
```

Note that `fp` points to `sp + 29`, so the three `str*`-instructions should fill up a 32bit - value at `sp + 28`, which is later used as the value `n` in `Ok(n) => written += n`. This doesn't work on ARMv5 as the `strh` can't write to the unaligned contents of `fp`, so the upper bits of `n` won't get cleared, leading to the assertion failure in Vec::drain.

With `+strict-align`, the code works as expected.
bors added a commit that referenced this pull request Jun 1, 2017
Rollup of 9 pull requests

- Successful merges: #42136, #42275, #42286, #42297, #42302, #42306, #42314, #42324, #42347
- Failed merges:
@bors bors merged commit 4450807 into rust-lang:master Jun 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants