1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm64-linux-gnu | FileCheck %s 3; RUN: llc < %s -global-isel -mtriple=arm64-linux-gnu | FileCheck %s --check-prefix=GISEL 4 5@x1 = external hidden global [2 x i64] 6@x2 = external hidden global [16777216 x i64] 7@x3 = external hidden global { [9 x ptr], [8 x ptr] } 8 9define i64 @f1() { 10; CHECK-LABEL: f1: 11; CHECK: // %bb.0: 12; CHECK-NEXT: adrp x8, x1+16 13; CHECK-NEXT: ldr x0, [x8, :lo12:x1+16] 14; CHECK-NEXT: ret 15; 16; GISEL-LABEL: f1: 17; GISEL: // %bb.0: 18; GISEL-NEXT: adrp x8, x1+16 19; GISEL-NEXT: ldr x0, [x8, :lo12:x1+16] 20; GISEL-NEXT: ret 21 %l = load i64, ptr getelementptr ([2 x i64], ptr @x1, i64 0, i64 2) 22 ret i64 %l 23} 24 25define i64 @f2() { 26; CHECK-LABEL: f2: 27; CHECK: // %bb.0: 28; CHECK-NEXT: adrp x8, x1 29; CHECK-NEXT: add x8, x8, :lo12:x1 30; CHECK-NEXT: ldr x0, [x8, #24] 31; CHECK-NEXT: ret 32; 33; GISEL-LABEL: f2: 34; GISEL: // %bb.0: 35; GISEL-NEXT: adrp x8, x1 36; GISEL-NEXT: add x8, x8, :lo12:x1 37; GISEL-NEXT: ldr x0, [x8, #24] 38; GISEL-NEXT: ret 39 40 %l = load i64, ptr getelementptr ([2 x i64], ptr @x1, i64 0, i64 3) 41 ret i64 %l 42} 43 44define i64 @f3() { 45; CHECK-LABEL: f3: 46; CHECK: // %bb.0: 47; CHECK-NEXT: adrp x8, x1+1 48; CHECK-NEXT: add x8, x8, :lo12:x1+1 49; CHECK-NEXT: ldr x0, [x8] 50; CHECK-NEXT: ret 51; 52; GISEL-LABEL: f3: 53; GISEL: // %bb.0: 54; GISEL-NEXT: adrp x8, x1+1 55; GISEL-NEXT: add x8, x8, :lo12:x1+1 56; GISEL-NEXT: ldr x0, [x8] 57; GISEL-NEXT: ret 58 %l = load i64, ptr getelementptr (i8, ptr @x1, i64 1) 59 ret i64 %l 60} 61 62define [2 x i64] @f4() { 63; FIXME: GlobalISel misses the opportunity to form a LDP here. 64; 65; CHECK-LABEL: f4: 66; CHECK: // %bb.0: 67; CHECK-NEXT: adrp x8, x2+8 68; CHECK-NEXT: add x8, x8, :lo12:x2+8 69; CHECK-NEXT: ldp x0, x1, [x8] 70; CHECK-NEXT: ret 71; 72; GISEL-LABEL: f4: 73; GISEL: // %bb.0: 74; GISEL-NEXT: adrp x8, x2+8 75; GISEL-NEXT: adrp x9, x2+8 76; GISEL-NEXT: add x9, x9, :lo12:x2+8 77; GISEL-NEXT: ldr x0, [x8, :lo12:x2+8] 78; GISEL-NEXT: ldr x1, [x9, #8] 79; GISEL-NEXT: ret 80 %l = load [2 x i64], ptr getelementptr (i8, ptr @x2, i64 8) 81 ret [2 x i64] %l 82} 83 84define i64 @f5() { 85; CHECK-LABEL: f5: 86; CHECK: // %bb.0: 87; CHECK-NEXT: adrp x8, x2+1048568 88; CHECK-NEXT: ldr x0, [x8, :lo12:x2+1048568] 89; CHECK-NEXT: ret 90; 91; GISEL-LABEL: f5: 92; GISEL: // %bb.0: 93; GISEL-NEXT: adrp x8, x2+1048568 94; GISEL-NEXT: ldr x0, [x8, :lo12:x2+1048568] 95; GISEL-NEXT: ret 96 %l = load i64, ptr getelementptr ([16777216 x i64], ptr @x2, i64 0, i64 131071) 97 ret i64 %l 98} 99 100define i64 @f6() { 101; CHECK-LABEL: f6: 102; CHECK: // %bb.0: 103; CHECK-NEXT: mov w8, #1048576 104; CHECK-NEXT: adrp x9, x2 105; CHECK-NEXT: add x9, x9, :lo12:x2 106; CHECK-NEXT: ldr x0, [x9, x8] 107; CHECK-NEXT: ret 108; 109; GISEL-LABEL: f6: 110; GISEL: // %bb.0: 111; GISEL-NEXT: mov w8, #1048576 112; GISEL-NEXT: adrp x9, x2 113; GISEL-NEXT: add x9, x9, :lo12:x2 114; GISEL-NEXT: ldr x0, [x9, x8] 115; GISEL-NEXT: ret 116 %l = load i64, ptr getelementptr ([16777216 x i64], ptr @x2, i64 0, i64 131072) 117 ret i64 %l 118} 119 120define i32 @f7() { 121; CHECK-LABEL: f7: 122; CHECK: // %bb.0: // %entry 123; CHECK-NEXT: adrp x8, x3+108 124; CHECK-NEXT: ldr w0, [x8, :lo12:x3+108] 125; CHECK-NEXT: ret 126; 127; GISEL-LABEL: f7: 128; GISEL: // %bb.0: // %entry 129; GISEL-NEXT: adrp x8, x3+108 130; GISEL-NEXT: ldr w0, [x8, :lo12:x3+108] 131; GISEL-NEXT: ret 132 133entry: 134 %lshr = lshr i128 bitcast (<2 x i64> <i64 undef, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @x3, i64 0, i32 1, i64 2) to i64)> to i128), 64 135 %trunc = trunc i128 %lshr to i64 136 %inttoptr = inttoptr i64 %trunc to ptr 137 %gep = getelementptr i32, ptr %inttoptr, i64 5 138 %l = load i32, ptr %gep 139 ret i32 %l 140} 141