Repository: rust
Issue: Wrong code generation in core library with ROPI-RWPI relocation model on ARMv7em.
Labels: A-LLVM,O-Arm,P-medium,T-compiler,C-bug

### TL; DR version:
When targeting `thumbv7em-none-eabi` with `ropi-rwpi` relocation model, some generated instructions in `core::fmt::num` are wrong. The below naive example won't work in the **debug** build.
```rust
#[no_mangle]
pub extern "C" fn main() -> ! {
    // It prints out "2;", not "256".
    hprintln!("{}", 256);  // ARM semihosting print.
    loop {}
}
```

To reproduce, see the repo below:
https://github.com/Acciente717/ropi-rwpi-err-demo

### Detailed version:
Tracking down with GDB, the wrong instructions are in `_ZN4core3fmt3num3imp7fmt_u32#hash`. The corresponding rust source code is [here](https://github.com/rust-lang/rust/blob/3ea44938e21f0de8ae7d4f6399a8a30f97867c70/library/core/src/fmt/num.rs#L211-L274).

The specific Rust statement leading to wrong instructions is:
```rust
static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
      2021222324252627282930313233343536373839\
      4041424344454647484950515253545556575859\
      6061626364656667686970717273747576777879\
      8081828384858687888990919293949596979899";

let lut_ptr = DEC_DIGITS_LUT.as_ptr();
```

The wrong instructions are:
```
805b322:  f243 7124   movw  r1, #14116    ; 0x3724
805b326:  f2c0 0101   movt  r1, #1
805b32a:  4648        mov   r0, r9
805b32c:  5840        ldr   r0, [r0, r1]
805b32e:  21c8        movs  r1, #200    ; 0xc8
805b330:  f003 fc29   bl    805eb86 <_ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$6as_ptr17h58e80ef4ecfdc5b4E>
```

#### Why is it wrong?
In ROPI-RWPI relocation model, read-only data should be stored in Flash, and is accessed by PC-relative addressing. Read-write data should be stored in SRAM, and is accessed by R9-relative addressing. R9 is reserved for this purpose in RWPI, and is called the "static base".

`DEC_DIGITS_LUT` is read-only, but the generated code uses R9-relative addressing. It is essentially accessing some wild memory.

#### Do you have a minimal example?
Unfortunately, no. As can be seen in the GitHub repo linked above, I tried to pull out the function from `core` and compile it alone. But this time, the compiler gives out the correct instructions:
```
80007d2:  f241 504a   movw  r0, #5450    ; 0x154a
80007d6:  f2c0 0006   movt  r0, #6
80007da:  4478        add   r0, pc
80007dc:  6800        ldr   r0, [r0, #0]
80007de:  21c8        movs  r1, #200    ; 0xc8
80007e0:  f05e f9d1   bl    805eb86 <_ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$6as_ptr17h58e80ef4ecfdc5b4E>
```

I have no idea how to fix the bug by myself, but I would like to participate in diagnosing and get it fixed as soon as possible.

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.62.0-nightly (f4a7ce997 2022-04-08)
binary: rustc
commit-hash: f4a7ce997a1d7546d2b737f8b87d36907bcea2ad
commit-date: 2022-04-08
host: x86_64-unknown-linux-gnu
release: 1.62.0-nightly
LLVM version: 14.0.0
```