llvm/llvm/test/CodeGen/AArch64/tiny-model-pic.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK-PIC
; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -fast-isel < %s | FileCheck %s --check-prefix=CHECK-PIC
; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -global-isel < %s | FileCheck %s --check-prefix=CHECK-PIC-GLOBISEL

; Note fast-isel tests here will fall back to isel

@src = external local_unnamed_addr global [65536 x i8], align 1
@dst = external global [65536 x i8], align 1
@ptr = external local_unnamed_addr global ptr, align 8

define dso_preemptable void @foo1() {
; CHECK-PIC-LABEL: foo1:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    ldr x8, :got:src
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    ldr x9, :got:dst
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: foo1:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    ldr x8, :got:src
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, :got:dst
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @src, align 1
  store i8 %0, ptr @dst, align 1
  ret void
}

define dso_preemptable void @foo2() {
; CHECK-PIC-LABEL: foo2:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    ldr x8, :got:ptr
; CHECK-PIC-NEXT:    ldr x9, :got:dst
; CHECK-PIC-NEXT:    str x9, [x8]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: foo2:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    ldr x8, :got:ptr
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, :got:dst
; CHECK-PIC-GLOBISEL-NEXT:    str x9, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  store ptr @dst, ptr @ptr, align 8
  ret void
}

define dso_preemptable void @foo3() {
; FIXME: Needn't adr ptr
;
; CHECK-PIC-LABEL: foo3:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    ldr x8, :got:src
; CHECK-PIC-NEXT:    ldr x9, :got:ptr
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    ldr x9, [x9]
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: foo3:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    ldr x8, :got:src
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, :got:ptr
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @src, align 1
  %1 = load ptr, ptr @ptr, align 8
  store i8 %0, ptr %1, align 1
  ret void
}

@lsrc = internal global i8 0, align 4
@ldst = internal global i8 0, align 4
@lptr = internal global ptr null, align 8

define dso_preemptable void @bar1() {
; CHECK-PIC-LABEL: bar1:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lsrc
; CHECK-PIC-NEXT:    adr x9, ldst
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: bar1:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lsrc
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, ldst
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @lsrc, align 4
  store i8 %0, ptr @ldst, align 4
  ret void
}

define dso_preemptable void @bar2() {
; CHECK-PIC-LABEL: bar2:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lptr
; CHECK-PIC-NEXT:    adr x9, ldst
; CHECK-PIC-NEXT:    str x9, [x8]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: bar2:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lptr
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, ldst
; CHECK-PIC-GLOBISEL-NEXT:    str x9, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  store ptr @ldst, ptr @lptr, align 8
  ret void
}

define dso_preemptable void @bar3() {
; FIXME: Needn't adr lptr
;
; CHECK-PIC-LABEL: bar3:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lsrc
; CHECK-PIC-NEXT:    ldr x9, lptr
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: bar3:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lsrc
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, lptr
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @lsrc, align 4
  %1 = load ptr, ptr @lptr, align 8
  store i8 %0, ptr %1, align 1
  ret void
}


@lbsrc = internal global [65536 x i8] zeroinitializer, align 4
@lbdst = internal global [65536 x i8] zeroinitializer, align 4

define dso_preemptable void @baz1() {
; CHECK-PIC-LABEL: baz1:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lbsrc
; CHECK-PIC-NEXT:    adr x9, lbdst
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: baz1:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lbsrc
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, lbdst
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @lbsrc, align 4
  store i8 %0, ptr @lbdst, align 4
  ret void
}

define dso_preemptable void @baz2() {
; CHECK-PIC-LABEL: baz2:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lptr
; CHECK-PIC-NEXT:    adr x9, lbdst
; CHECK-PIC-NEXT:    str x9, [x8]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: baz2:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lptr
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, lbdst
; CHECK-PIC-GLOBISEL-NEXT:    str x9, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  store ptr @lbdst, ptr @lptr, align 8
  ret void
}

define dso_preemptable void @baz3() {
; FIXME: Needn't adr lptr
;
; CHECK-PIC-LABEL: baz3:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    adr x8, lbsrc
; CHECK-PIC-NEXT:    ldr x9, lptr
; CHECK-PIC-NEXT:    ldrb w8, [x8]
; CHECK-PIC-NEXT:    strb w8, [x9]
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: baz3:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    adr x8, lbsrc
; CHECK-PIC-GLOBISEL-NEXT:    adr x9, lptr
; CHECK-PIC-GLOBISEL-NEXT:    ldrb w8, [x8]
; CHECK-PIC-GLOBISEL-NEXT:    ldr x9, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    strb w8, [x9]
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
  %0 = load i8, ptr @lbsrc, align 4
  %1 = load ptr, ptr @lptr, align 8
  store i8 %0, ptr %1, align 1
  ret void
}


declare void @func(...)

define dso_preemptable ptr @externfuncaddr() {
; CHECK-PIC-LABEL: externfuncaddr:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    ldr x0, :got:func
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: externfuncaddr:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    ldr x0, :got:func
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
      ret ptr @func
}

define dso_preemptable ptr @localfuncaddr() {
; CHECK-PIC-LABEL: localfuncaddr:
; CHECK-PIC:       // %bb.0: // %entry
; CHECK-PIC-NEXT:    ldr x0, :got:externfuncaddr
; CHECK-PIC-NEXT:    ret
;
; CHECK-PIC-GLOBISEL-LABEL: localfuncaddr:
; CHECK-PIC-GLOBISEL:       // %bb.0: // %entry
; CHECK-PIC-GLOBISEL-NEXT:    ldr x0, :got:externfuncaddr
; CHECK-PIC-GLOBISEL-NEXT:    ret
entry:
      ret ptr @externfuncaddr
}