Repository: rust
Issue: Reordered LLVM-IR bbs causing `FileCheck` failures on `aarch64-unknown-none`
Labels: A-LLVM,A-testsuite,T-compiler,C-bug,O-AArch64

This issue came to my attention as it happens on a custom target that we use on ferrocene to test `aarch64-unknown-none`. However, I was able to reproduce it here as well (on commit 9a21ac8e7ef) and it might cause some errors in the future

The `FileCheck` test on `tests/codegen/vec_pop_push_noop.rs` will fail if the basic blocks of the LLVM-IR for the `noop` function are reordered in such a way that the returning block is not at the end. 

This is the IR on `x86_64-unknown-linux-gnu` (which passes the test):

```llvm
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read, inaccessiblemem: write) uwtable
define void @noop(ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %v) unnamed_addr #2 personality ptr @rust_eh_personality {
start:
  %0 = getelementptr inbounds i8, ptr %v, i64 16
  %_4 = load i64, ptr %0, align 8, !noundef !3
  %1 = icmp eq i64 %_4, 0
  br i1 %1, label %bb1, label %"_ZN5alloc3vec16Vec$LT$T$C$A$GT$4push17h6b95231b811ede1dE.exit"

"_ZN5alloc3vec16Vec$LT$T$C$A$GT$4push17h6b95231b811ede1dE.exit": ; preds = %start
  %2 = add i64 %_4, -1
  %_7 = load i64, ptr %v, align 8, !noundef !3
  %_5 = icmp ult i64 %2, %_7
  tail call void @llvm.assume(i1 %_5)
  br label %bb1

bb1:                                              ; preds = %start, %"_ZN5alloc3vec16Vec$LT$T$C$A$GT$4push17h6b95231b811ede1dE.exit"
  ret void
}
```
And this is the IR on `aarch64-unknown-none`

```llvm
; Function Attrs: mustprogress nofree norecurse noredzone nosync nounwind willreturn memory(argmem: read, inaccessiblemem: write)
define dso_local void @noop(ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %v) unnamed_addr #3 {
start:
  %0 = getelementptr inbounds i8, ptr %v, i64 16
  %_2.i = load i64, ptr %0, align 8, !alias.scope !19, !noundef !1
  %.not = icmp eq i64 %_2.i, 0
  br i1 %.not, label %bb3, label %bb7

bb3:                                              ; preds = %start, %bb7
  ret void

bb7:                                              ; preds = %start
  %1 = add i64 %_2.i, -1
  %2 = load i64, ptr %v, align 8, !noundef !1
  %cond.i = icmp ult i64 %1, %2
  tail call void @llvm.assume(i1 %cond.i)
  br label %bb3
}
```

This is the `config.toml` I used:
```toml
[llvm]
download-ci-llvm = false
assertions = true
static-libstdcpp = true

[build]
host = ["x86_64-unknown-linux-gnu"]
target = ["aarch64-unknown-none"]
docs = false
extended = true
tools = [
   "cargo",
   "clippy",
   "rustdoc",
   "rustfmt",
   "rust-analyzer",
   "rust-analyzer-proc-macro-srv",
   "analysis",
   "src",
   "rust-demangler",  ]
sanitizers = true
cargo-native-static = true
metrics = false

[rust]
debug-assertions = true
channel = "dev"
lld = false
remap-debuginfo = true

[dist]
```

I had to update the `vec_pop_push_noop.rs` test so it uses `alloc` instead of `std`:
```rust
//@ compile-flags: -O
#![no_std]
#![crate_type = "lib"]
extern crate alloc;
#[no_mangle]
// CHECK-LABEL: @noop(
pub fn noop(v: &mut alloc::vec::Vec<u8>) {
    // CHECK-NOT: grow_one
    // CHECK-NOT: call
    // CHECK: tail call void @llvm.assume
    // CHECK-NOT: grow_one
    // CHECK-NOT: call
    // CHECK: ret
    if let Some(x) = v.pop() {
        v.push(x)
    }
}

#[no_mangle]
// CHECK-LABEL: @push_byte(
pub fn push_byte(v: &mut alloc::vec::Vec<u8>) {
    // CHECK: call {{.*}}grow_one
    v.push(3);
}
```

And finally run:
```bash
$ ./x.py test tests/codegen/vec_pop_push_noop.rs
```

This is the error:
```
./tests/codegen/vec_pop_push_noop.rs:13:12: error: CHECK: expected string not found in input
 // CHECK: ret
           ^
./vec_pop_push_noop.ll:270:29: note: scanning from here
 tail call void @llvm.assume(i1 %cond.i)
                            ^
./vec_pop_push_noop.ll:274:21: note: possible intended match here
; Function Attrs: noredzone nounwind
                    ^

Input file: ./vec_pop_push_noop.ll
Check file: ./tests/codegen/vec_pop_push_noop.rs

-dump-input=help explains the following input dump.

Input was: ...
```