1; RUN: llc -mtriple armv7-linux -relocation-model=ropi -mattr=-no-movt,+v8m -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,RW-DEFAULT-MOVT,RW-DEFAULT,ROPI-MOVT,ROPI 2; RUN: llc -mtriple armv7-linux -relocation-model=ropi -mattr=+no-movt -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,RW-DEFAULT-NOMOVT,RW-DEFAULT,ROPI-NOMOVT,ROPI 3; RUN: llc -mtriple armv7-linux -relocation-model=rwpi -mattr=-no-movt,+v8m -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,RO-DEFAULT-MOVT,RO-DEFAULT,RWPI-MOVT,RWPI 4; RUN: llc -mtriple armv7-linux -relocation-model=rwpi -mattr=+no-movt -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,RO-DEFAULT-NOMOVT,RO-DEFAULT,RWPI-NOMOVT,RWPI 5; RUN: llc -mtriple armv7-linux -relocation-model=ropi-rwpi -mattr=-no-movt,+v8m -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,ROPI-MOVT,ROPI,RWPI-MOVT,RWPI 6; RUN: llc -mtriple armv7-linux -relocation-model=ropi-rwpi -mattr=+no-movt -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,ROPI-NOMOVT,ROPI,RWPI-NOMOVT,RWPI 7 8@internal_global = internal global i32 42 9define i32 @test_internal_global() { 10; CHECK-LABEL: test_internal_global: 11; RW-DEFAULT-MOVT: movw r[[ADDR:[0-9]+]], :lower16:internal_global 12; RW-DEFAULT-MOVT-NEXT: movt r[[ADDR]], :upper16:internal_global 13; RW-DEFAULT-NOMOVT: ldr r[[ADDR:[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 14; RW-DEFAULT-NEXT: ldr r0, [r[[ADDR]]] 15; RW-DEFAULT-NEXT: bx lr 16; RW-DEFAULT-NOMOVT: [[LABEL]]: 17; RW-DEFAULT-NOMOVT-NEXT: .long internal_global 18 19; RWPI-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:internal_global(sbrel) 20; RWPI-MOVT-NEXT: movt [[OFFSET]], :upper16:internal_global(sbrel) 21; RWPI-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 22; RWPI-NEXT: add r[[ADDR:[0-9]+]], r9, [[OFFSET]] 23; RWPI-NEXT: ldr r0, [r[[ADDR]]] 24; RWPI-NEXT: bx lr 25; RWPI-NOMOVT: [[LABEL]]: 26; RWPI-NOMOVT-NEXT: .long internal_global(sbrel) 27entry: 28 %v = load i32, i32* @internal_global 29 ret i32 %v 30} 31 32@external_global = external global i32 33define i32 @test_external_global() { 34; CHECK-LABEL: test_external_global: 35; RW-DEFAULT-MOVT: movw r[[ADDR:[0-9]+]], :lower16:external_global 36; RW-DEFAULT-MOVT-NEXT: movt r[[ADDR]], :upper16:external_global 37; RW-DEFAULT-NOMOVT: ldr r[[ADDR:[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 38; RW-DEFAULT-NEXT: ldr r0, [r[[ADDR]]] 39; RW-DEFAULT-NEXT: bx lr 40; RW-DEFAULT-NOMOVT: [[LABEL]]: 41; RW-DEFAULT-NOMOVT: .long external_global 42 43; RWPI-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:external_global(sbrel) 44; RWPI-MOVT-NEXT: movt [[OFFSET]], :upper16:external_global(sbrel) 45; RWPI-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 46; RWPI-NEXT: add r[[ADDR:[0-9]+]], r9, [[OFFSET]] 47; RWPI-NEXT: ldr r0, [r[[ADDR]]] 48; RWPI-NEXT: bx lr 49; RWPI-NOMOVT: [[LABEL]]: 50; RWPI-NOMOVT-NEXT: .long external_global(sbrel) 51entry: 52 %v = load i32, i32* @external_global 53 ret i32 %v 54} 55 56@internal_constant = internal constant i32 42 57define i32 @test_internal_constant() { 58; CHECK-LABEL: test_internal_constant: 59; ROPI-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:(internal_constant-([[ANCHOR:.L[[:alnum:]_]+]]+8) 60; ROPI-MOVT-NEXT: movt [[OFFSET]], :upper16:(internal_constant-([[ANCHOR]]+8) 61; ROPI-MOVT-NEXT: [[ANCHOR]]: 62; ROPI-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 63; ROPI-NOMOVT-NEXT: [[ANCHOR:.L[[:alnum:]_]+]]: 64; ROPI-NEXT: add r[[ADDR:[0-9]+]], pc, [[OFFSET]] 65; ROPI-NEXT: ldr r0, [r[[ADDR]]] 66; ROPI-NEXT: bx lr 67; ROPI-NOMOVT: [[LABEL]]: 68; ROPI-NOMOVT-NEXT: .long internal_constant-([[ANCHOR]]+8) 69 70; RO-DEFAULT-MOVT: movw r[[ADDR:[0-9]+]], :lower16:internal_constant 71; RO-DEFAULT-MOVT-NEXT: movt r[[ADDR]], :upper16:internal_constant 72; RO-DEFAULT-NOMOVT: ldr r[[ADDR:[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 73; RO-DEFAULT-NEXT: ldr r0, [r[[ADDR]]] 74; RO-DEFAULT-NEXT: bx lr 75; RO-DEFAULT-NOMOVT: [[LABEL]]: 76; RO-DEFAULT-NOMOVT-NEXT: .long internal_constant 77entry: 78 %v = load i32, i32* @internal_constant 79 ret i32 %v 80} 81 82@external_constant = external constant i32 83define i32 @test_external_constant() { 84; CHECK-LABEL: test_external_constant: 85; ROPI-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:(external_constant-([[ANCHOR:.L[[:alnum:]_]+]]+8) 86; ROPI-MOVT-NEXT: movt [[OFFSET]], :upper16:(external_constant-([[ANCHOR]]+8) 87; ROPI-MOVT-NEXT: [[ANCHOR]]: 88; ROPI-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 89; ROPI-NOMOVT-NEXT: [[ANCHOR:.L[[:alnum:]_]+]]: 90; ROPI-NEXT: add r[[ADDR:[0-9]+]], pc, [[OFFSET]] 91; ROPI-NEXT: ldr r0, [r[[ADDR]]] 92; ROPI-NEXT: bx lr 93; ROPI-NOMOVT: [[LABEL]]: 94; ROPI-NOMOVT-NEXT: .long external_constant-([[ANCHOR]]+8) 95 96; RO-DEFAULT-MOVT: movw r[[ADDR:[0-9]+]], :lower16:external_constant 97; RO-DEFAULT-MOVT-NEXT: movt r[[ADDR]], :upper16:external_constant 98; RO-DEFAULT-NOMOVT: ldr r[[ADDR:[0-9]+]], [[LABEL:.L[[:alnum:]_]+]] 99; RO-DEFAULT-NEXT: ldr r0, [r[[ADDR]]] 100; RO-DEFAULT-NEXT: bx lr 101; RO-DEFAULT-NOMOVT: [[LABEL]]: 102; RO-DEFAULT-NOMOVT: .long external_constant 103entry: 104 %v = load i32, i32* @external_constant 105 ret i32 %v 106} 107 108; RW-DEFAULT-NOMOVT: internal_global: 109; RW-DEFAULT-NOMOVT: .long 42 110; RW-DEFAULT-NOMOVT: .size internal_global, 4 111 112; RWPI-NOMOVT: internal_global: 113; RWPI-NOMOVT: .long 42 114; RWPI-NOMOVT: .size internal_global, 4 115 116; ROPI-NOMOVT: internal_constant: 117; ROPI-NOMOVT: .long 42 118; ROPI-NOMOVT: .size internal_constant, 4 119 120; RO-DEFAULT-NOMOVT: internal_constant: 121; RO-DEFAULT-NOMOVT: .long 42 122; RO-DEFAULT-NOMOVT: .size internal_constant, 4 123