llvm/llvm/test/CodeGen/AArch64/GlobalISel/merge-stores-truncating.mir

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple aarch64 -run-pass=loadstore-opt -verify-machineinstrs %s -o - | FileCheck %s
---
name:            trunc_i16_to_i8
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: trunc_i16_to_i8
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY1]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %2:_(s32) = COPY $w0
    %0:_(s16) = G_TRUNC %2(s32)
    %1:_(p0) = COPY $x1
    %4:_(s16) = G_CONSTANT i16 8
    %3:_(s8) = G_TRUNC %0(s16)
    %5:_(s16) = G_LSHR %0, %4(s16)
    %6:_(s8) = G_TRUNC %5(s16)
    G_STORE %3(s8), %1(p0) :: (store (s8))
    %7:_(s64) = G_CONSTANT i64 1
    %8:_(p0) = G_PTR_ADD %1, %7(s64)
    G_STORE %6(s8), %8(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            trunc_i32_to_i8
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: trunc_i32_to_i8
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[COPY]](s32), [[COPY1]](p0) :: (store (s32), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %3:_(s32) = G_CONSTANT i32 8
    %6:_(s32) = G_CONSTANT i32 16
    %9:_(s32) = G_CONSTANT i32 24
    %2:_(s8) = G_TRUNC %0(s32)
    %4:_(s32) = G_LSHR %0, %3(s32)
    %5:_(s8) = G_TRUNC %4(s32)
    %7:_(s32) = G_LSHR %0, %6(s32)
    %8:_(s8) = G_TRUNC %7(s32)
    %10:_(s32) = G_LSHR %0, %9(s32)
    %11:_(s8) = G_TRUNC %10(s32)
    G_STORE %2(s8), %1(p0) :: (store (s8))
    %12:_(s64) = G_CONSTANT i64 1
    %13:_(p0) = G_PTR_ADD %1, %12(s64)
    G_STORE %5(s8), %13(p0) :: (store (s8))
    %14:_(s64) = G_CONSTANT i64 2
    %15:_(p0) = G_PTR_ADD %1, %14(s64)
    G_STORE %8(s8), %15(p0) :: (store (s8))
    %16:_(s64) = G_CONSTANT i64 3
    %17:_(p0) = G_PTR_ADD %1, %16(s64)
    G_STORE %11(s8), %17(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            trunc_i32_to_i16
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: trunc_i32_to_i16
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[COPY]](s32), [[COPY1]](p0) :: (store (s32), align 2)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %3:_(s32) = G_CONSTANT i32 16
    %2:_(s16) = G_TRUNC %0(s32)
    %4:_(s32) = G_LSHR %0, %3(s32)
    %5:_(s16) = G_TRUNC %4(s32)
    G_STORE %2(s16), %1(p0) :: (store (s16))
    %6:_(s64) = G_CONSTANT i64 2
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %5(s16), %7(p0) :: (store (s16))
    RET_ReallyLR

...
---
name:            be_i32_to_i16
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: be_i32_to_i16
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: G_STORE [[ROTR]](s32), [[COPY1]](p0) :: (store (s32), align 2)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %2:_(s32) = G_CONSTANT i32 16
    %3:_(s32) = G_LSHR %0, %2(s32)
    %4:_(s16) = G_TRUNC %0(s32)
    %5:_(s16) = G_TRUNC %3(s32)
    %6:_(s64) = G_CONSTANT i64 2
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %4(s16), %7(p0) :: (store (s16))
    G_STORE %5(s16), %1(p0) :: (store (s16))
    RET_ReallyLR

...
---
name:            be_i32_to_i16_order
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: be_i32_to_i16_order
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: G_STORE [[ROTR]](s32), [[COPY1]](p0) :: (store (s32), align 2)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %2:_(s32) = G_CONSTANT i32 16
    %3:_(s32) = G_LSHR %0, %2(s32)
    %4:_(s16) = G_TRUNC %0(s32)
    %5:_(s16) = G_TRUNC %3(s32)
    %6:_(s64) = G_CONSTANT i64 2
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %5(s16), %1(p0) :: (store (s16))
    G_STORE %4(s16), %7(p0) :: (store (s16))
    RET_ReallyLR

...
---
name:            trunc_i64_to_i8
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$x0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: trunc_i64_to_i8
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[COPY]](s64), [[COPY1]](p0) :: (store (s64), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s64) = COPY $x0
    %1:_(p0) = COPY $x1
    %3:_(s64) = G_CONSTANT i64 8
    %6:_(s64) = G_CONSTANT i64 16
    %9:_(s64) = G_CONSTANT i64 24
    %12:_(s64) = G_CONSTANT i64 32
    %15:_(s64) = G_CONSTANT i64 40
    %18:_(s64) = G_CONSTANT i64 48
    %21:_(s64) = G_CONSTANT i64 56
    %2:_(s8) = G_TRUNC %0(s64)
    %4:_(s64) = G_LSHR %0, %3(s64)
    %5:_(s8) = G_TRUNC %4(s64)
    %7:_(s64) = G_LSHR %0, %6(s64)
    %8:_(s8) = G_TRUNC %7(s64)
    %10:_(s64) = G_LSHR %0, %9(s64)
    %11:_(s8) = G_TRUNC %10(s64)
    %13:_(s64) = G_LSHR %0, %12(s64)
    %14:_(s8) = G_TRUNC %13(s64)
    %16:_(s64) = G_LSHR %0, %15(s64)
    %17:_(s8) = G_TRUNC %16(s64)
    %19:_(s64) = G_LSHR %0, %18(s64)
    %20:_(s8) = G_TRUNC %19(s64)
    %22:_(s64) = G_LSHR %0, %21(s64)
    %23:_(s8) = G_TRUNC %22(s64)
    G_STORE %2(s8), %1(p0) :: (store (s8))
    %24:_(s64) = G_CONSTANT i64 1
    %25:_(p0) = G_PTR_ADD %1, %24(s64)
    G_STORE %5(s8), %25(p0) :: (store (s8))
    %26:_(s64) = G_CONSTANT i64 2
    %27:_(p0) = G_PTR_ADD %1, %26(s64)
    G_STORE %8(s8), %27(p0) :: (store (s8))
    %28:_(s64) = G_CONSTANT i64 3
    %29:_(p0) = G_PTR_ADD %1, %28(s64)
    G_STORE %11(s8), %29(p0) :: (store (s8))
    %30:_(s64) = G_CONSTANT i64 4
    %31:_(p0) = G_PTR_ADD %1, %30(s64)
    G_STORE %14(s8), %31(p0) :: (store (s8))
    %32:_(s64) = G_CONSTANT i64 5
    %33:_(p0) = G_PTR_ADD %1, %32(s64)
    G_STORE %17(s8), %33(p0) :: (store (s8))
    %34:_(s64) = G_CONSTANT i64 6
    %35:_(p0) = G_PTR_ADD %1, %34(s64)
    G_STORE %20(s8), %35(p0) :: (store (s8))
    %36:_(s64) = G_CONSTANT i64 7
    %37:_(p0) = G_PTR_ADD %1, %36(s64)
    G_STORE %23(s8), %37(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            trunc_i64_to_i16
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$x0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: trunc_i64_to_i16
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[COPY]](s64), [[COPY1]](p0) :: (store (s64), align 2)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s64) = COPY $x0
    %1:_(p0) = COPY $x1
    %3:_(s64) = G_CONSTANT i64 16
    %6:_(s64) = G_CONSTANT i64 32
    %9:_(s64) = G_CONSTANT i64 48
    %2:_(s16) = G_TRUNC %0(s64)
    %4:_(s64) = G_LSHR %0, %3(s64)
    %5:_(s16) = G_TRUNC %4(s64)
    %7:_(s64) = G_LSHR %0, %6(s64)
    %8:_(s16) = G_TRUNC %7(s64)
    %10:_(s64) = G_LSHR %0, %9(s64)
    %11:_(s16) = G_TRUNC %10(s64)
    G_STORE %2(s16), %1(p0) :: (store (s16))
    %12:_(s64) = G_CONSTANT i64 2
    %13:_(p0) = G_PTR_ADD %1, %12(s64)
    G_STORE %5(s16), %13(p0) :: (store (s16))
    %14:_(s64) = G_CONSTANT i64 4
    %15:_(p0) = G_PTR_ADD %1, %14(s64)
    G_STORE %8(s16), %15(p0) :: (store (s16))
    %16:_(s64) = G_CONSTANT i64 6
    %17:_(p0) = G_PTR_ADD %1, %16(s64)
    G_STORE %11(s16), %17(p0) :: (store (s16))
    RET_ReallyLR

...
---
name:            trunc_i64_to_i32
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$x0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: trunc_i64_to_i32
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: G_STORE [[COPY]](s64), [[COPY1]](p0) :: (store (s64), align 4)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s64) = COPY $x0
    %1:_(p0) = COPY $x1
    %3:_(s64) = G_CONSTANT i64 32
    %2:_(s32) = G_TRUNC %0(s64)
    %4:_(s64) = G_LSHR %0, %3(s64)
    %5:_(s32) = G_TRUNC %4(s64)
    G_STORE %2(s32), %1(p0) :: (store (s32))
    %6:_(s64) = G_CONSTANT i64 4
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %5(s32), %7(p0) :: (store (s32))
    RET_ReallyLR

...
---
name:            be_i64_to_i32
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$x0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: be_i64_to_i32
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[COPY]], [[C]](s64)
    ; CHECK-NEXT: G_STORE [[ROTR]](s64), [[COPY1]](p0) :: (store (s64), align 4)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s64) = COPY $x0
    %1:_(p0) = COPY $x1
    %2:_(s64) = G_CONSTANT i64 32
    %3:_(s64) = G_LSHR %0, %2(s64)
    %4:_(s32) = G_TRUNC %0(s64)
    %5:_(s32) = G_TRUNC %3(s64)
    %6:_(s64) = G_CONSTANT i64 4
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %4(s32), %7(p0) :: (store (s32))
    G_STORE %5(s32), %1(p0) :: (store (s32))
    RET_ReallyLR

...
---
name:            be_i64_to_i32_order
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$x0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: be_i64_to_i32_order
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s64) = G_ROTR [[COPY]], [[C]](s64)
    ; CHECK-NEXT: G_STORE [[ROTR]](s64), [[COPY1]](p0) :: (store (s64), align 4)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s64) = COPY $x0
    %1:_(p0) = COPY $x1
    %2:_(s64) = G_CONSTANT i64 32
    %3:_(s64) = G_LSHR %0, %2(s64)
    %4:_(s32) = G_TRUNC %0(s64)
    %5:_(s32) = G_TRUNC %3(s64)
    %6:_(s64) = G_CONSTANT i64 4
    %7:_(p0) = G_PTR_ADD %1, %6(s64)
    G_STORE %5(s32), %1(p0) :: (store (s32))
    G_STORE %4(s32), %7(p0) :: (store (s32))
    RET_ReallyLR

...
---
name:            merge_hole
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: merge_hole
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s8), [[COPY1]](p0) :: (store (s8))
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s16), [[PTR_ADD]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %5:_(s32) = G_CONSTANT i32 16
    %2:_(s64) = G_CONSTANT i64 2
    %3:_(p0) = G_PTR_ADD %1, %2(s64)
    %4:_(s8) = G_TRUNC %0(s32)
    G_STORE %4(s8), %1(p0) :: (store (s8))
    %6:_(s32) = G_LSHR %0, %5(s32)
    %7:_(s16) = G_TRUNC %6(s32)
    G_STORE %7(s16), %3(p0) :: (store (s16), align 1)
    RET_ReallyLR

...
---
name:            merge_hole2
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: merge_hole2
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[PTR_ADD]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s8), [[COPY1]](p0) :: (store (s8))
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %4:_(s32) = G_CONSTANT i32 16
    %2:_(s64) = G_CONSTANT i64 2
    %3:_(p0) = G_PTR_ADD %1, %2(s64)
    %5:_(s32) = G_LSHR %0, %4(s32)
    %6:_(s16) = G_TRUNC %5(s32)
    G_STORE %6(s16), %3(p0) :: (store (s16), align 1)
    %7:_(s8) = G_TRUNC %0(s32)
    G_STORE %7(s8), %1(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            merge_hole3
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: merge_hole3
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C2]](s64)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s16), [[PTR_ADD1]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %7:_(s32) = G_CONSTANT i32 16
    %2:_(s64) = G_CONSTANT i64 1
    %3:_(p0) = G_PTR_ADD %1, %2(s64)
    %4:_(s64) = G_CONSTANT i64 2
    %5:_(p0) = G_PTR_ADD %1, %4(s64)
    %6:_(s8) = G_TRUNC %0(s32)
    G_STORE %6(s8), %3(p0) :: (store (s8))
    %8:_(s32) = G_LSHR %0, %7(s32)
    %9:_(s16) = G_TRUNC %8(s32)
    G_STORE %9(s16), %5(p0) :: (store (s16), align 1)
    RET_ReallyLR

...
---
name:            merge_hole4
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: merge_hole4
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s16), [[COPY1]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %5:_(s32) = G_CONSTANT i32 16
    %2:_(s64) = G_CONSTANT i64 2
    %3:_(p0) = G_PTR_ADD %1, %2(s64)
    %4:_(s8) = G_TRUNC %0(s32)
    G_STORE %4(s8), %3(p0) :: (store (s8))
    %6:_(s32) = G_LSHR %0, %5(s32)
    %7:_(s16) = G_TRUNC %6(s32)
    G_STORE %7(s16), %1(p0) :: (store (s16), align 1)
    RET_ReallyLR

...
---
name:            load_between_stores
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
  - { reg: '$x2' }
body:             |
  bb.1:
    liveins: $w0, $x1, $x2

    ; CHECK-LABEL: name: load_between_stores
    ; CHECK: liveins: $w0, $x1, $x2
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY1]](p0) :: (store (s16))
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY2]](p0) :: (load (s32))
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s16), [[PTR_ADD]](p0) :: (store (s16))
    ; CHECK-NEXT: $w0 = COPY [[LOAD]](s32)
    ; CHECK-NEXT: RET_ReallyLR implicit $w0
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %2:_(p0) = COPY $x2
    %4:_(s32) = G_CONSTANT i32 16
    %3:_(s16) = G_TRUNC %0(s32)
    %5:_(s32) = G_LSHR %0, %4(s32)
    %6:_(s16) = G_TRUNC %5(s32)
    G_STORE %3(s16), %1(p0) :: (store (s16))
    %7:_(s32) = G_LOAD %2(p0) :: (load (s32))
    %8:_(s64) = G_CONSTANT i64 2
    %9:_(p0) = G_PTR_ADD %1, %8(s64)
    G_STORE %6(s16), %9(p0) :: (store (s16))
    $w0 = COPY %7(s32)
    RET_ReallyLR implicit $w0

...
---
name:            invalid_shift
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: invalid_shift
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 4
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[TRUNC]](s16)
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s16) = G_LSHR [[TRUNC]], [[C]](s16)
    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[LSHR]](s16)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s8), [[COPY1]](p0) :: (store (s8))
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: G_STORE [[TRUNC2]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: RET_ReallyLR
    %2:_(s32) = COPY $w0
    %0:_(s16) = G_TRUNC %2(s32)
    %1:_(p0) = COPY $x1
    %4:_(s16) = G_CONSTANT i16 4
    %3:_(s8) = G_TRUNC %0(s16)
    %5:_(s16) = G_LSHR %0, %4(s16)
    %6:_(s8) = G_TRUNC %5(s16)
    G_STORE %3(s8), %1(p0) :: (store (s8))
    %7:_(s64) = G_CONSTANT i64 1
    %8:_(p0) = G_PTR_ADD %1, %7(s64)
    G_STORE %6(s8), %8(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            missing_store
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: missing_store
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[COPY]], [[C]](s32)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[LSHR]](s32)
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s16), [[COPY1]](p0) :: (store (s16), align 1)
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: G_STORE [[TRUNC]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: RET_ReallyLR
    %0:_(s32) = COPY $w0
    %1:_(p0) = COPY $x1
    %3:_(s32) = G_CONSTANT i32 8
    %6:_(s32) = G_CONSTANT i32 24
    %2:_(s8) = G_TRUNC %0(s32)
    %4:_(s32) = G_LSHR %0, %3(s32)
    %5:_(s8) = G_TRUNC %4(s32)
    %7:_(s32) = G_LSHR %0, %6(s32)
    %8:_(s8) = G_TRUNC %7(s32)
    G_STORE %2(s8), %1(p0) :: (store (s8))
    %9:_(s64) = G_CONSTANT i64 1
    %10:_(p0) = G_PTR_ADD %1, %9(s64)
    G_STORE %5(s8), %10(p0) :: (store (s8))
    %11:_(s64) = G_CONSTANT i64 3
    %12:_(p0) = G_PTR_ADD %1, %11(s64)
    G_STORE %8(s8), %12(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            different_base_reg
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
  - { reg: '$x2' }
body:             |
  bb.1:
    liveins: $w0, $x1, $x2

    ; CHECK-LABEL: name: different_base_reg
    ; CHECK: liveins: $w0, $x1, $x2
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[TRUNC]](s16)
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s16) = G_LSHR [[TRUNC]], [[C]](s16)
    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[LSHR]](s16)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s8), [[COPY1]](p0) :: (store (s8))
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY2]], [[C1]](s64)
    ; CHECK-NEXT: G_STORE [[TRUNC2]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: RET_ReallyLR
    %3:_(s32) = COPY $w0
    %0:_(s16) = G_TRUNC %3(s32)
    %1:_(p0) = COPY $x1
    %2:_(p0) = COPY $x2
    %5:_(s16) = G_CONSTANT i16 8
    %4:_(s8) = G_TRUNC %0(s16)
    %6:_(s16) = G_LSHR %0, %5(s16)
    %7:_(s8) = G_TRUNC %6(s16)
    G_STORE %4(s8), %1(p0) :: (store (s8))
    %8:_(s64) = G_CONSTANT i64 1
    %9:_(p0) = G_PTR_ADD %2, %8(s64)
    G_STORE %7(s8), %9(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            second_store_is_volatile
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $w0, $x1

    ; CHECK-LABEL: name: second_store_is_volatile
    ; CHECK: liveins: $w0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[TRUNC]](s16)
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s16) = G_LSHR [[TRUNC]], [[C]](s16)
    ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[LSHR]](s16)
    ; CHECK-NEXT: G_STORE [[TRUNC1]](s8), [[COPY1]](p0) :: (volatile store (s8))
    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
    ; CHECK-NEXT: G_STORE [[TRUNC2]](s8), [[PTR_ADD]](p0) :: (store (s8))
    ; CHECK-NEXT: RET_ReallyLR
    %2:_(s32) = COPY $w0
    %0:_(s16) = G_TRUNC %2(s32)
    %1:_(p0) = COPY $x1
    %4:_(s16) = G_CONSTANT i16 8
    %3:_(s8) = G_TRUNC %0(s16)
    %5:_(s16) = G_LSHR %0, %4(s16)
    %6:_(s8) = G_TRUNC %5(s16)
    G_STORE %3(s8), %1(p0) :: (volatile store (s8))
    %7:_(s64) = G_CONSTANT i64 1
    %8:_(p0) = G_PTR_ADD %1, %7(s64)
    G_STORE %6(s8), %8(p0) :: (store (s8))
    RET_ReallyLR

...
---
name:            wide_not_multiple_of_mem_ty
alignment:       4
tracksRegLiveness: true
liveins:
  - { reg: '$w0' }
  - { reg: '$x1' }
body:             |
  bb.1:
    liveins: $x0, $x1

    ; CHECK-LABEL: name: wide_not_multiple_of_mem_ty
    ; CHECK: liveins: $x0, $x1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s48) = G_TRUNC [[COPY]](s64)
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s48) = G_LSHR [[TRUNC]], [[C]](s64)
    ; CHECK-NEXT: %trunc:_(s32) = G_TRUNC [[LSHR]](s48)
    ; CHECK-NEXT: G_STORE %trunc(s32), [[COPY1]](p0) :: (store (s32))
    ; CHECK-NEXT: RET_ReallyLR
    %2:_(s64) = COPY $x0
    %0:_(s48) = G_TRUNC %2(s64)
    %1:_(p0) = COPY $x1
    %4:_(s64) = G_CONSTANT i64 32
    %5:_(s48) = G_LSHR %0, %4(s64)
    %trunc:_(s32) = G_TRUNC %5(s48)
    G_STORE %trunc(s32), %1(p0) :: (store (s32))
    RET_ReallyLR

...