llvm.org GIT mirror llvm / c878642
AArch64: Allow offsets to be folded into addresses with ELF. This is a code size win in code that takes offseted addresses frequently, such as C++ constructors that typically need to compute an offseted address of a vtable. It reduces the size of Chromium for Android's .text section by 46KB, or 56KB with ThinLTO (which exposes more opportunities to use a direct access rather than a GOT access). Because the addend range is limited in COFF and Mach-O, this is enabled for ELF only. Differential Revision: https://reviews.llvm.org/D45199 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@329611 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 1 year, 7 months ago
13 changed file(s) with 237 addition(s) and 166 deletion(s). Raw diff Collapse all Expand all
742742 if (!GAN)
743743 return true;
744744
745 const GlobalValue *GV = GAN->getGlobal();
746 unsigned Alignment = GV->getAlignment();
747 Type *Ty = GV->getValueType();
748 if (Alignment == 0 && Ty->isSized())
749 Alignment = DL.getABITypeAlignment(Ty);
750
751 if (Alignment >= Size)
752 return true;
745 if (GAN->getOffset() % Size == 0) {
746 const GlobalValue *GV = GAN->getGlobal();
747 unsigned Alignment = GV->getAlignment();
748 Type *Ty = GV->getValueType();
749 if (Alignment == 0 && Ty->isSized())
750 Alignment = DL.getABITypeAlignment(Ty);
751
752 if (Alignment >= Size)
753 return true;
754 }
753755 }
754756
755757 if (CurDAG->isBaseWithConstantOffset(N)) {
36743674 SDValue AArch64TargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty,
36753675 SelectionDAG &DAG,
36763676 unsigned Flag) const {
3677 return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag);
3677 return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty,
3678 N->getOffset(), Flag);
36783679 }
36793680
36803681 SDValue AArch64TargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty,
37483749 : AArch64II::MO_NO_FLAG);
37493750 unsigned char OpFlags =
37503751 Subtarget->ClassifyGlobalReference(GV, getTargetMachine());
3751
3752 assert(cast(Op)->getOffset() == 0 &&
3753 "unexpected offset in global node");
3752 if (OpFlags != AArch64II::MO_NO_FLAG)
3753 assert(cast(Op)->getOffset() == 0 &&
3754 "unexpected offset in global node");
37543755
37553756 // This also catches the large code model case for Darwin.
37563757 if ((OpFlags & AArch64II::MO_GOT) != 0) {
49884989
49894990 bool AArch64TargetLowering::isOffsetFoldingLegal(
49904991 const GlobalAddressSDNode *GA) const {
4991 DEBUG(dbgs() << "Skipping offset folding global address: ");
4992 DEBUG(GA->dump());
4993 DEBUG(dbgs() << "AArch64 doesn't support folding offsets into global "
4994 "addresses\n");
4995 return false;
4992 // FIXME: Only ELF can represent the full range of possible addends here, as
4993 // the format stores the addend in a 64-bit field. With Mach-O the equivalent
4994 // field is 24 bits, and with COFF it is 21 bits. To make this work with the
4995 // other object formats we will need to arrange to prevent the addend from
4996 // going out of bounds.
4997 if (!getTargetMachine().getTargetTriple().isOSBinFormatELF())
4998 return false;
4999 return Subtarget->ClassifyGlobalReference(
5000 GA->getGlobal(), getTargetMachine()) == AArch64II::MO_NO_FLAG;
49965001 }
49975002
49985003 bool AArch64TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
55 ; The important thing for this test is that we need an unaligned load of `l_b'
66 ; ("ldr w2, [x1, #8]" in this case).
77
8 ; CHECK: adrp x[[PAGE:[0-9]+]], {{l_b@PAGE|.Lb}}
9 ; CHECK: add x[[ADDR:[0-9]+]], x[[PAGE]], {{l_b@PAGEOFF|:lo12:.Lb}}
10 ; CHECK-NEXT: ldr [[VAL:w[0-9]+]], [x[[ADDR]], #8]
11 ; CHECK-NEXT: str [[VAL]], [x0, #8]
12 ; CHECK-NEXT: ldr [[VAL2:x[0-9]+]], [x[[ADDR]]]
13 ; CHECK-NEXT: str [[VAL2]], [x0]
8 ; CHECK: adrp x[[PAGE:[0-9]+]], .Lb+8
9 ; CHECK-NEXT: ldr [[VAL:w[0-9]+]], [x[[PAGE]], :lo12:.Lb+8]
10 ; CHECK-NEXT: str [[VAL]], [x0, #8]
11 ; CHECK-NEXT: adrp x[[ADDR:[0-9]+]], .Lb
12 ; CHECK-NEXT: add x[[ADDR]], x[[ADDR]], :lo12:.Lb
13 ; CHECK-NEXT: ldr [[VAL2:x[0-9]+]], [x[[ADDR]]]
14 ; CHECK-NEXT: str [[VAL2]], [x0]
1415
1516 define void @foo(i8* %a) {
1617 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4 bitcast ([3 x i32]* @b to i8*), i64 12, i1 false)
44
55 ; base + offset (imm9)
66 ; CHECK: @t1
7 ; CHECK: ldr xzr, [x{{[0-9]+}}, #8]
7 ; CHECK: ldr xzr, [x0, #8]
88 ; CHECK: ret
9 define void @t1() {
10 %incdec.ptr = getelementptr inbounds i64, i64* @object, i64 1
9 define void @t1(i64* %object) {
10 %incdec.ptr = getelementptr inbounds i64, i64* %object, i64 1
1111 %tmp = load volatile i64, i64* %incdec.ptr, align 8
1212 ret void
1313 }
1414
1515 ; base + offset (> imm9)
1616 ; CHECK: @t2
17 ; CHECK: sub [[ADDREG:x[0-9]+]], x{{[0-9]+}}, #264
17 ; CHECK: sub [[ADDREG:x[0-9]+]], x0, #264
1818 ; CHECK: ldr xzr, [
19 ; CHECK: [[ADDREG]]]
2019 ; CHECK: ret
21 define void @t2() {
22 %incdec.ptr = getelementptr inbounds i64, i64* @object, i64 -33
20 define void @t2(i64* %object) {
21 %incdec.ptr = getelementptr inbounds i64, i64* %object, i64 -33
2322 %tmp = load volatile i64, i64* %incdec.ptr, align 8
2423 ret void
2524 }
2625
2726 ; base + unsigned offset (> imm9 and <= imm12 * size of type in bytes)
2827 ; CHECK: @t3
29 ; CHECK: ldr xzr, [x{{[0-9]+}}, #32760]
28 ; CHECK: ldr xzr, [x0, #32760]
3029 ; CHECK: ret
31 define void @t3() {
32 %incdec.ptr = getelementptr inbounds i64, i64* @object, i64 4095
30 define void @t3(i64* %object) {
31 %incdec.ptr = getelementptr inbounds i64, i64* %object, i64 4095
3332 %tmp = load volatile i64, i64* %incdec.ptr, align 8
3433 ret void
3534 }
3736 ; base + unsigned offset (> imm12 * size of type in bytes)
3837 ; CHECK: @t4
3938 ; CHECK: orr w[[NUM:[0-9]+]], wzr, #0x8000
40 ; CHECK: ldr xzr, [x{{[0-9]+}}, x[[NUM]]]
39 ; CHECK: ldr xzr, [x0, x[[NUM]]]
4140 ; CHECK: ret
42 define void @t4() {
43 %incdec.ptr = getelementptr inbounds i64, i64* @object, i64 4096
41 define void @t4(i64* %object) {
42 %incdec.ptr = getelementptr inbounds i64, i64* %object, i64 4096
4443 %tmp = load volatile i64, i64* %incdec.ptr, align 8
4544 ret void
4645 }
5756
5857 ; base + reg + imm
5958 ; CHECK: @t6
60 ; CHECK: add [[ADDREG:x[0-9]+]], x{{[0-9]+}}, x{{[0-9]+}}, lsl #3
59 ; CHECK: add [[ADDREG:x[0-9]+]], x1, x0, lsl #3
6160 ; CHECK-NEXT: orr w[[NUM:[0-9]+]], wzr, #0x8000
6261 ; CHECK: ldr xzr, [x{{[0-9]+}}, x[[NUM]]]
6362 ; CHECK: ret
64 define void @t6(i64 %a) {
65 %tmp1 = getelementptr inbounds i64, i64* @object, i64 %a
63 define void @t6(i64 %a, i64* %object) {
64 %tmp1 = getelementptr inbounds i64, i64* %object, i64 %a
6665 %incdec.ptr = getelementptr inbounds i64, i64* %tmp1, i64 4096
6766 %tmp = load volatile i64, i64* %incdec.ptr, align 8
6867 ret void
2828 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
2929 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
3030
31 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
31 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
32 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
3233 %val = atomicrmw nand i128* %p, i128 %bits release
3334 store i128 %val, i128* @var, align 16
3435 ret void
4344 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
4445 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
4546
46 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
47 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
48 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
4749 %val = atomicrmw or i128* %p, i128 %bits seq_cst
4850 store i128 %val, i128* @var, align 16
4951 ret void
5860 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
5961 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
6062
61 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
63 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
64 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
6265 %val = atomicrmw add i128* %p, i128 %bits seq_cst
6366 store i128 %val, i128* @var, align 16
6467 ret void
7376 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
7477 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
7578
76 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
79 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
80 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
7781 %val = atomicrmw sub i128* %p, i128 %bits seq_cst
7882 store i128 %val, i128* @var, align 16
7983 ret void
9498 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
9599 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
96100
97 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
101 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
102 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
98103 %val = atomicrmw min i128* %p, i128 %bits seq_cst
99104 store i128 %val, i128* @var, align 16
100105 ret void
115120 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
116121 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
117122
118 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
123 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
124 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
119125 %val = atomicrmw max i128* %p, i128 %bits seq_cst
120126 store i128 %val, i128* @var, align 16
121127 ret void
136142 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
137143 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
138144
139 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
145 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
146 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
140147 %val = atomicrmw umin i128* %p, i128 %bits seq_cst
141148 store i128 %val, i128* @var, align 16
142149 ret void
157164 ; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
158165 ; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
159166
160 ; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
167 ; CHECK-DAG: str [[DEST_REGLO]], [{{.*}}, :lo12:var]
168 ; CHECK-DAG: str [[DEST_REGHI]], [{{.*}}, :lo12:var+8]
161169 %val = atomicrmw umax i128* %p, i128 %bits seq_cst
162170 store i128 %val, i128* @var, align 16
163171 ret void
1515 define i32 @t0() {
1616 entry:
1717 ; CHECK-LABEL: t0:
18 ; CHECK: ldrb [[REG0:w[0-9]+]], [x[[BASEREG:[0-9]+]], #10]
19 ; CHECK: strb [[REG0]], [x[[BASEREG2:[0-9]+]], #10]
20 ; CHECK: ldrh [[REG1:w[0-9]+]], [x[[BASEREG]], #8]
21 ; CHECK: strh [[REG1]], [x[[BASEREG2]], #8]
18 ; CHECK: ldrb [[REG0:w[0-9]+]], [{{x[0-9]+}}, :lo12:src+10]
19 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:src+8
20 ; CHECK: strb [[REG0]], [{{x[0-9]+}}, :lo12:dst+10]
21 ; CHECK: ldrh [[REG1:w[0-9]+]], [x[[BASEREG]]]
22 ; CHECK: add x[[BASEREG2:[0-9]+]], {{x[0-9]+}}, :lo12:dst+8
23 ; CHECK: strh [[REG1]], [x[[BASEREG2]]]
2224 ; CHECK: ldr [[REG2:x[0-9]+]],
2325 ; CHECK: str [[REG2]],
2426 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 getelementptr inbounds (%struct.x, %struct.x* @dst, i32 0, i32 0), i8* align 8 getelementptr inbounds (%struct.x, %struct.x* @src, i32 0, i32 0), i32 11, i1 false)
2830 define void @t1(i8* nocapture %C) nounwind {
2931 entry:
3032 ; CHECK-LABEL: t1:
31 ; CHECK: ldur [[DEST:q[0-9]+]], [x[[BASEREG:[0-9]+]], #15]
33 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str1+15
34 ; CHECK: ldr [[DEST:q[0-9]+]], [x[[BASEREG:[0-9]+]]]
3235 ; CHECK: stur [[DEST]], [x0, #15]
3336 ; CHECK: ldr [[DEST:q[0-9]+]], [x[[BASEREG]]]
3437 ; CHECK: str [[DEST]], [x0]
4245 ; CHECK: mov [[REG3:w[0-9]+]]
4346 ; CHECK: movk [[REG3]],
4447 ; CHECK: str [[REG3]], [x0, #32]
45 ; CHECK: ldp [[DEST1:q[0-9]+]], [[DEST2:q[0-9]+]], [x{{[0-9]+}}]
48 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str2+16
49 ; CHECK: ldr [[DEST2:q[0-9]+]], [x[[BASEREG]]]
50 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str2
51 ; CHECK: ldr [[DEST1:q[0-9]+]], [x[[BASEREG]]]
4652 ; CHECK: stp [[DEST1]], [[DEST2]], [x0]
4753 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str2, i64 0, i64 0), i64 36, i1 false)
4854 ret void
5157 define void @t3(i8* nocapture %C) nounwind {
5258 entry:
5359 ; CHECK-LABEL: t3:
54 ; CHECK: ldr [[REG4:x[0-9]+]], [x[[BASEREG:[0-9]+]], #16]
60 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str3+16
61 ; CHECK: ldr [[REG4:x[0-9]+]], [x[[BASEREG]]]
5562 ; CHECK: str [[REG4]], [x0, #16]
63 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str3
5664 ; CHECK: ldr [[DEST:q[0-9]+]], [x[[BASEREG]]]
5765 ; CHECK: str [[DEST]], [x0]
5866 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str3, i64 0, i64 0), i64 24, i1 false)
8694 define void @t6() nounwind {
8795 entry:
8896 ; CHECK-LABEL: t6:
89 ; CHECK: ldur [[REG9:x[0-9]+]], [x{{[0-9]+}}, #6]
90 ; CHECK: stur [[REG9]], [x{{[0-9]+}}, #6]
97 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:.L.str6+6
98 ; CHECK: ldr [[REG9:x[0-9]+]], [x[[BASEREG]]]
99 ; CHECK: add x[[BASEREG:[0-9]+]], {{x[0-9]+}}, :lo12:spool.splbuf+6
100 ; CHECK: str [[REG9]], [x[[BASEREG]]]
91101 ; CHECK: ldr
92102 ; CHECK: str
93103 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([512 x i8], [512 x i8]* @spool.splbuf, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str6, i64 0, i64 0), i64 14, i1 false)
77 ; Check that no scheduling dependencies are created between the paired loads and the store during post-RA MI scheduling.
88 ;
99 ; CHECK-LABEL: # Machine code for function foo:
10 ; CHECK: SU(2): renamable $w{{[0-9]+}}, renamable $w{{[0-9]+}} = LDPWi
10 ; CHECK: SU(1): renamable $w{{[0-9]+}} = LDRWui
1111 ; CHECK: Successors:
12 ; CHECK-NOT: ch SU(4)
13 ; CHECK: SU(3)
14 ; CHECK: SU(4): STRWui $wzr, renamable $x{{[0-9]+}}
12 ; CHECK-NOT: SU(5)
13 ; CHECK: SU(2)
14 ; CHECK: SU(3): renamable $w{{[0-9]+}} = LDRWui
15 ; CHECK: Successors:
16 ; CHECK-NOT: SU(5)
17 ; CHECK: SU(4)
18 ; CHECK: SU(5): STRWui $wzr, renamable $x{{[0-9]+}}
1519 define i32 @foo() {
1620 entry:
1721 %0 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 0), align 4
1010 ; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]]
1111 ; CHECK: add [[STACK_TOP:x[0-9]+]], sp, #[[STACKSIZE]]
1212
13 ; CHECK: adrp x[[VA_LIST_HI:[0-9]+]], var
14 ; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, :lo12:var
15
1613 ; CHECK: stp x1, x2, [sp, #[[GR_BASE:[0-9]+]]]
1714 ; ... omit middle ones ...
1815 ; CHECK: str x7, [sp, #
2118 ; ... omit middle ones ...
2219 ; CHECK: stp q6, q7, [sp, #
2320
24 ; CHECK: str [[STACK_TOP]], [x[[VA_LIST]]]
21 ; CHECK: str [[STACK_TOP]], [{{[x[0-9]+}}, :lo12:var]
2522
2623 ; CHECK: add [[GR_TOPTMP:x[0-9]+]], sp, #[[GR_BASE]]
2724 ; CHECK: add [[GR_TOP:x[0-9]+]], [[GR_TOPTMP]], #56
28 ; CHECK: str [[GR_TOP]], [x[[VA_LIST]], #8]
25 ; CHECK: str [[GR_TOP]], [{{[x[0-9]+}}, :lo12:var+8]
2926
3027 ; CHECK: mov [[VR_TOPTMP:x[0-9]+]], sp
3128 ; CHECK: add [[VR_TOP:x[0-9]+]], [[VR_TOPTMP]], #128
32 ; CHECK: str [[VR_TOP]], [x[[VA_LIST]], #16]
29 ; CHECK: str [[VR_TOP]], [{{[x[0-9]+}}, :lo12:var+16]
3330
34 ; CHECK: mov [[GRVR:x[0-9]+]], #-545460846720
35 ; CHECK: movk [[GRVR]], #65480
36 ; CHECK: str [[GRVR]], [x[[VA_LIST]], #24]
31 ; CHECK: mov [[GRVR1:w[0-9]+]], #-56
32 ; CHECK: str [[GRVR1]], [{{[x[0-9]+}}, :lo12:var+24]
33 ; CHECK: orr [[GRVR2:w[0-9]+]], wzr, #0xffffff80
34 ; CHECK: str [[GRVR2]], [{{[x[0-9]+}}, :lo12:var+28]
3735
3836 %addr = bitcast %va_list* @var to i8*
3937 call void @llvm.va_start(i8* %addr)
4644 ; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]]
4745 ; CHECK: add [[STACK_TOP:x[0-9]+]], sp, #[[STACKSIZE]]
4846
49 ; CHECK: adrp x[[VA_LIST_HI:[0-9]+]], var
50 ; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, :lo12:var
51
5247 ; CHECK: stp x3, x4, [sp, #[[GR_BASE:[0-9]+]]]
5348 ; ... omit middle ones ...
5449 ; CHECK: str x7, [sp, #
5752 ; ... omit middle ones ...
5853 ; CHECK: str q7, [sp, #
5954
60 ; CHECK: str [[STACK_TOP]], [x[[VA_LIST]]]
55 ; CHECK: str [[STACK_TOP]], [{{[x[0-9]+}}, :lo12:var]
6156
6257 ; CHECK: add [[GR_TOPTMP:x[0-9]+]], sp, #[[GR_BASE]]
6358 ; CHECK: add [[GR_TOP:x[0-9]+]], [[GR_TOPTMP]], #40
64 ; CHECK: str [[GR_TOP]], [x[[VA_LIST]], #8]
59 ; CHECK: str [[GR_TOP]], [{{[x[0-9]+}}, :lo12:var+8]
6560
6661 ; CHECK: mov [[VR_TOPTMP:x[0-9]+]], sp
6762 ; CHECK: add [[VR_TOP:x[0-9]+]], [[VR_TOPTMP]], #112
68 ; CHECK: str [[VR_TOP]], [x[[VA_LIST]], #16]
63 ; CHECK: str [[VR_TOP]], [{{[x[0-9]+}}, :lo12:var+16]
6964
70 ; CHECK: mov [[GRVR_OFFS:x[0-9]+]], #-40
71 ; CHECK: movk [[GRVR_OFFS]], #65424, lsl #32
72 ; CHECK: str [[GRVR_OFFS]], [x[[VA_LIST]], #24]
65 ; CHECK: mov [[GRVR1:w[0-9]+]], #-40
66 ; CHECK: str [[GRVR1]], [{{[x[0-9]+}}, :lo12:var+24]
67 ; CHECK: mov [[GRVR2:w[0-9]+]], #-112
68 ; CHECK: str [[GRVR2]], [{{[x[0-9]+}}, :lo12:var+28]
7369
7470 %addr = bitcast %va_list* @var to i8*
7571 call void @llvm.va_start(i8* %addr)
8480 call void @llvm.va_start(i8* %addr)
8581 ; CHECK-NOT: sub sp, sp
8682 ; CHECK: mov [[STACK:x[0-9]+]], sp
87 ; CHECK: add x[[VAR:[0-9]+]], {{x[0-9]+}}, :lo12:var
88 ; CHECK: str [[STACK]], [x[[VAR]]]
83 ; CHECK: str [[STACK]], [{{[x[0-9]+}}, :lo12:var]
8984
9085 ret void
9186 }
9691 ; CHECK-LABEL: test_offsetstack:
9792 ; CHECK: stp {{q[0-9]+}}, {{q[0-9]+}}, [sp, #-80]!
9893 ; CHECK: add [[STACK_TOP:x[0-9]+]], sp, #96
99 ; CHECK: add x[[VAR:[0-9]+]], {{x[0-9]+}}, :lo12:var
100 ; CHECK: str [[STACK_TOP]], [x[[VAR]]]
94 ; CHECK: str [[STACK_TOP]], [{{[x[0-9]+}}, :lo12:var]
10195
10296 %addr = bitcast %va_list* @var to i8*
10397 call void @llvm.va_start(i8* %addr)
128122 call void @llvm.va_copy(i8* %dstaddr, i8* %srcaddr)
129123
130124 ; CHECK: add x[[SRC:[0-9]+]], {{x[0-9]+}}, :lo12:var
131
132125 ; CHECK: ldr [[BLOCK:q[0-9]+]], [x[[SRC]]]
133126 ; CHECK: add x[[DST:[0-9]+]], {{x[0-9]+}}, :lo12:second_list
134127 ; CHECK: str [[BLOCK]], [x[[DST]]]
135128
136 ; CHECK: ldr [[BLOCK:q[0-9]+]], [x[[SRC]], #16]
137 ; CHECK: str [[BLOCK]], [x[[DST]], #16]
129 ; CHECK: add x[[SRC:[0-9]+]], {{x[0-9]+}}, :lo12:var+16
130 ; CHECK: ldr [[BLOCK:q[0-9]+]], [x[[SRC]]]
131 ; CHECK: str [[BLOCK]], [x[[DST]]]
138132 ret void
139133 ; CHECK: ret
140134 }
263263
264264 ; Add a bunch of tests for rdar://13258794: Match LDUR/STUR for D and Q
265265 ; registers for unscaled vector accesses
266 @str = global [63 x i8] c"Test case for rdar://13258794: LDUR/STUR for D and Q registers\00", align 1
267
268 define <1 x i64> @fct0() nounwind readonly ssp {
266
267 define <1 x i64> @fct0(i8* %str) nounwind readonly ssp {
269268 entry:
270269 ; CHECK-LABEL: fct0:
271270 ; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #3]
272 %0 = load <1 x i64>, <1 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <1 x i64>*), align 8
271 %p = getelementptr inbounds i8, i8* %str, i64 3
272 %q = bitcast i8* %p to <1 x i64>*
273 %0 = load <1 x i64>, <1 x i64>* %q, align 8
273274 ret <1 x i64> %0
274275 }
275276
276 define <2 x i32> @fct1() nounwind readonly ssp {
277 define <2 x i32> @fct1(i8* %str) nounwind readonly ssp {
277278 entry:
278279 ; CHECK-LABEL: fct1:
279280 ; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #3]
280 %0 = load <2 x i32>, <2 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <2 x i32>*), align 8
281 %p = getelementptr inbounds i8, i8* %str, i64 3
282 %q = bitcast i8* %p to <2 x i32>*
283 %0 = load <2 x i32>, <2 x i32>* %q, align 8
281284 ret <2 x i32> %0
282285 }
283286
284 define <4 x i16> @fct2() nounwind readonly ssp {
287 define <4 x i16> @fct2(i8* %str) nounwind readonly ssp {
285288 entry:
286289 ; CHECK-LABEL: fct2:
287290 ; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #3]
288 %0 = load <4 x i16>, <4 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <4 x i16>*), align 8
291 %p = getelementptr inbounds i8, i8* %str, i64 3
292 %q = bitcast i8* %p to <4 x i16>*
293 %0 = load <4 x i16>, <4 x i16>* %q, align 8
289294 ret <4 x i16> %0
290295 }
291296
292 define <8 x i8> @fct3() nounwind readonly ssp {
297 define <8 x i8> @fct3(i8* %str) nounwind readonly ssp {
293298 entry:
294299 ; CHECK-LABEL: fct3:
295300 ; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #3]
296 %0 = load <8 x i8>, <8 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <8 x i8>*), align 8
301 %p = getelementptr inbounds i8, i8* %str, i64 3
302 %q = bitcast i8* %p to <8 x i8>*
303 %0 = load <8 x i8>, <8 x i8>* %q, align 8
297304 ret <8 x i8> %0
298305 }
299306
300 define <2 x i64> @fct4() nounwind readonly ssp {
307 define <2 x i64> @fct4(i8* %str) nounwind readonly ssp {
301308 entry:
302309 ; CHECK-LABEL: fct4:
303310 ; CHECK: ldur {{q[0-9]+}}, [{{x[0-9]+}}, #3]
304 %0 = load <2 x i64>, <2 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <2 x i64>*), align 16
311 %p = getelementptr inbounds i8, i8* %str, i64 3
312 %q = bitcast i8* %p to <2 x i64>*
313 %0 = load <2 x i64>, <2 x i64>* %q, align 16
305314 ret <2 x i64> %0
306315 }
307316
308 define <4 x i32> @fct5() nounwind readonly ssp {
317 define <4 x i32> @fct5(i8* %str) nounwind readonly ssp {
309318 entry:
310319 ; CHECK-LABEL: fct5:
311320 ; CHECK: ldur {{q[0-9]+}}, [{{x[0-9]+}}, #3]
312 %0 = load <4 x i32>, <4 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <4 x i32>*), align 16
321 %p = getelementptr inbounds i8, i8* %str, i64 3
322 %q = bitcast i8* %p to <4 x i32>*
323 %0 = load <4 x i32>, <4 x i32>* %q, align 16
313324 ret <4 x i32> %0
314325 }
315326
316 define <8 x i16> @fct6() nounwind readonly ssp {
327 define <8 x i16> @fct6(i8* %str) nounwind readonly ssp {
317328 entry:
318329 ; CHECK-LABEL: fct6:
319330 ; CHECK: ldur {{q[0-9]+}}, [{{x[0-9]+}}, #3]
320 %0 = load <8 x i16>, <8 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <8 x i16>*), align 16
331 %p = getelementptr inbounds i8, i8* %str, i64 3
332 %q = bitcast i8* %p to <8 x i16>*
333 %0 = load <8 x i16>, <8 x i16>* %q, align 16
321334 ret <8 x i16> %0
322335 }
323336
324 define <16 x i8> @fct7() nounwind readonly ssp {
337 define <16 x i8> @fct7(i8* %str) nounwind readonly ssp {
325338 entry:
326339 ; CHECK-LABEL: fct7:
327340 ; CHECK: ldur {{q[0-9]+}}, [{{x[0-9]+}}, #3]
328 %0 = load <16 x i8>, <16 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <16 x i8>*), align 16
341 %p = getelementptr inbounds i8, i8* %str, i64 3
342 %q = bitcast i8* %p to <16 x i8>*
343 %0 = load <16 x i8>, <16 x i8>* %q, align 16
329344 ret <16 x i8> %0
330345 }
331346
332 define void @fct8() nounwind ssp {
347 define void @fct8(i8* %str) nounwind ssp {
333348 entry:
334349 ; CHECK-LABEL: fct8:
335350 ; CHECK: ldur [[DESTREG:d[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
336351 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
337 %0 = load <1 x i64>, <1 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <1 x i64>*), align 8
338 store <1 x i64> %0, <1 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <1 x i64>*), align 8
339 ret void
340 }
341
342 define void @fct9() nounwind ssp {
352 %p = getelementptr inbounds i8, i8* %str, i64 3
353 %q = bitcast i8* %p to <1 x i64>*
354 %0 = load <1 x i64>, <1 x i64>* %q, align 8
355 %p2 = getelementptr inbounds i8, i8* %str, i64 4
356 %q2 = bitcast i8* %p2 to <1 x i64>*
357 store <1 x i64> %0, <1 x i64>* %q2, align 8
358 ret void
359 }
360
361 define void @fct9(i8* %str) nounwind ssp {
343362 entry:
344363 ; CHECK-LABEL: fct9:
345364 ; CHECK: ldur [[DESTREG:d[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
346365 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
347 %0 = load <2 x i32>, <2 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <2 x i32>*), align 8
348 store <2 x i32> %0, <2 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <2 x i32>*), align 8
349 ret void
350 }
351
352 define void @fct10() nounwind ssp {
366 %p = getelementptr inbounds i8, i8* %str, i64 3
367 %q = bitcast i8* %p to <2 x i32>*
368 %0 = load <2 x i32>, <2 x i32>* %q, align 8
369 %p2 = getelementptr inbounds i8, i8* %str, i64 4
370 %q2 = bitcast i8* %p2 to <2 x i32>*
371 store <2 x i32> %0, <2 x i32>* %q2, align 8
372 ret void
373 }
374
375 define void @fct10(i8* %str) nounwind ssp {
353376 entry:
354377 ; CHECK-LABEL: fct10:
355378 ; CHECK: ldur [[DESTREG:d[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
356379 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
357 %0 = load <4 x i16>, <4 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <4 x i16>*), align 8
358 store <4 x i16> %0, <4 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <4 x i16>*), align 8
359 ret void
360 }
361
362 define void @fct11() nounwind ssp {
380 %p = getelementptr inbounds i8, i8* %str, i64 3
381 %q = bitcast i8* %p to <4 x i16>*
382 %0 = load <4 x i16>, <4 x i16>* %q, align 8
383 %p2 = getelementptr inbounds i8, i8* %str, i64 4
384 %q2 = bitcast i8* %p2 to <4 x i16>*
385 store <4 x i16> %0, <4 x i16>* %q2, align 8
386 ret void
387 }
388
389 define void @fct11(i8* %str) nounwind ssp {
363390 entry:
364391 ; CHECK-LABEL: fct11:
365392 ; CHECK: ldur [[DESTREG:d[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
366393 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
367 %0 = load <8 x i8>, <8 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <8 x i8>*), align 8
368 store <8 x i8> %0, <8 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <8 x i8>*), align 8
369 ret void
370 }
371
372 define void @fct12() nounwind ssp {
394 %p = getelementptr inbounds i8, i8* %str, i64 3
395 %q = bitcast i8* %p to <8 x i8>*
396 %0 = load <8 x i8>, <8 x i8>* %q, align 8
397 %p2 = getelementptr inbounds i8, i8* %str, i64 4
398 %q2 = bitcast i8* %p2 to <8 x i8>*
399 store <8 x i8> %0, <8 x i8>* %q2, align 8
400 ret void
401 }
402
403 define void @fct12(i8* %str) nounwind ssp {
373404 entry:
374405 ; CHECK-LABEL: fct12:
375406 ; CHECK: ldur [[DESTREG:q[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
376407 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
377 %0 = load <2 x i64>, <2 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <2 x i64>*), align 16
378 store <2 x i64> %0, <2 x i64>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <2 x i64>*), align 16
379 ret void
380 }
381
382 define void @fct13() nounwind ssp {
408 %p = getelementptr inbounds i8, i8* %str, i64 3
409 %q = bitcast i8* %p to <2 x i64>*
410 %0 = load <2 x i64>, <2 x i64>* %q, align 16
411 %p2 = getelementptr inbounds i8, i8* %str, i64 4
412 %q2 = bitcast i8* %p2 to <2 x i64>*
413 store <2 x i64> %0, <2 x i64>* %q2, align 16
414 ret void
415 }
416
417 define void @fct13(i8* %str) nounwind ssp {
383418 entry:
384419 ; CHECK-LABEL: fct13:
385420 ; CHECK: ldur [[DESTREG:q[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
386421 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
387 %0 = load <4 x i32>, <4 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <4 x i32>*), align 16
388 store <4 x i32> %0, <4 x i32>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <4 x i32>*), align 16
389 ret void
390 }
391
392 define void @fct14() nounwind ssp {
422 %p = getelementptr inbounds i8, i8* %str, i64 3
423 %q = bitcast i8* %p to <4 x i32>*
424 %0 = load <4 x i32>, <4 x i32>* %q, align 16
425 %p2 = getelementptr inbounds i8, i8* %str, i64 4
426 %q2 = bitcast i8* %p2 to <4 x i32>*
427 store <4 x i32> %0, <4 x i32>* %q2, align 16
428 ret void
429 }
430
431 define void @fct14(i8* %str) nounwind ssp {
393432 entry:
394433 ; CHECK-LABEL: fct14:
395434 ; CHECK: ldur [[DESTREG:q[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
396435 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
397 %0 = load <8 x i16>, <8 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <8 x i16>*), align 16
398 store <8 x i16> %0, <8 x i16>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <8 x i16>*), align 16
399 ret void
400 }
401
402 define void @fct15() nounwind ssp {
436 %p = getelementptr inbounds i8, i8* %str, i64 3
437 %q = bitcast i8* %p to <8 x i16>*
438 %0 = load <8 x i16>, <8 x i16>* %q, align 16
439 %p2 = getelementptr inbounds i8, i8* %str, i64 4
440 %q2 = bitcast i8* %p2 to <8 x i16>*
441 store <8 x i16> %0, <8 x i16>* %q2, align 16
442 ret void
443 }
444
445 define void @fct15(i8* %str) nounwind ssp {
403446 entry:
404447 ; CHECK-LABEL: fct15:
405448 ; CHECK: ldur [[DESTREG:q[0-9]+]], {{\[}}[[BASEREG:x[0-9]+]], #3]
406449 ; CHECK: stur [[DESTREG]], {{\[}}[[BASEREG]], #4]
407 %0 = load <16 x i8>, <16 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 3) to <16 x i8>*), align 16
408 store <16 x i8> %0, <16 x i8>* bitcast (i8* getelementptr inbounds ([63 x i8], [63 x i8]* @str, i64 0, i64 4) to <16 x i8>*), align 16
450 %p = getelementptr inbounds i8, i8* %str, i64 3
451 %q = bitcast i8* %p to <16 x i8>*
452 %0 = load <16 x i8>, <16 x i8>* %q, align 16
453 %p2 = getelementptr inbounds i8, i8* %str, i64 4
454 %q2 = bitcast i8* %p2 to <16 x i8>*
455 store <16 x i8> %0, <16 x i8>* %q2, align 16
409456 ret void
410457 }
411458
8585 @var128 = global i128 0
8686 define {i128, i1} @test_cmpxchg_128_unsplit(i128* %addr) {
8787 ; CHECK-LABEL: test_cmpxchg_128_unsplit:
88 ; CHECK: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
89 ; CHECK: ldr [[DESIRED_HI:x[0-9]+]], [x[[VAR128]], #8]
90 ; CHECK: ldr [[DESIRED_LO:x[0-9]+]], [x[[VAR128]]]
91 ; CHECK: ldr [[NEW_HI:x[0-9]+]], [x[[VAR128]], #8]
92 ; CHECK: ldr [[NEW_LO:x[0-9]+]], [x[[VAR128]]]
88 ; CHECK: ldr [[DESIRED_HI:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128+8]
89 ; CHECK: ldr [[DESIRED_LO:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128]
90 ; CHECK: ldr [[NEW_HI:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128+8]
91 ; CHECK: ldr [[NEW_LO:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128]
9392 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
9493 ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0]
9594 ; CHECK: cmp [[OLD_LO]], [[DESIRED_LO]]
9595 %addr = bitcast %myStruct* @varstruct to [2 x i64]*
9696 %val = load [2 x i64], [2 x i64]* %addr
9797 ret [2 x i64] %val
98 ; CHECK: add x[[VARSTRUCT:[0-9]+]], {{x[0-9]+}}, :lo12:varstruct
99 ; CHECK: ldp x0, x1, [x[[VARSTRUCT]]]
98 ; CHECK: ldr x0, [{{x[0-9]+}}, :lo12:varstruct]
99 ; CHECK: ldr x1, [{{x[0-9]+}}, :lo12:varstruct+8]
100100 ; Make sure epilogue immediately follows
101101 ; CHECK-NEXT: ret
102102 }
163163 define i64 @check_i128_regalign(i32 %val0, i128 %val1, i64 %val2) {
164164 ; CHECK-LABEL: check_i128_regalign
165165 store i128 %val1, i128* @var128
166 ; CHECK-DAG: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
167 ; CHECK-DAG: stp x2, x3, [x[[VAR128]]]
166 ; CHECK-DAG: str x3, [{{x[0-9]+}}, :lo12:var128+8]
167 ; CHECK-DAG: str x2, [{{x[0-9]+}}, :lo12:var128]
168168
169169 ret i64 %val2
170170 ; CHECK-DAG: mov x0, x4
6161 %arr = call [2 x i64] @return_smallstruct()
6262 store [2 x i64] %arr, [2 x i64]* @varsmallstruct
6363 ; CHECK: bl return_smallstruct
64 ; CHECK: add x[[VARSMALLSTRUCT:[0-9]+]], {{x[0-9]+}}, :lo12:varsmallstruct
65 ; CHECK: stp x0, x1, [x[[VARSMALLSTRUCT]]]
64 ; CHECK: str x1, [{{x[0-9]+}}, {{#?}}:lo12:varsmallstruct+8]
65 ; CHECK: add x8, {{x[0-9]+}}, {{#?}}:lo12:varstruct
66 ; CHECK: str x0, [{{x[0-9]+}}, {{#?}}:lo12:varsmallstruct]
6667
6768 call void @return_large_struct(%myStruct* sret @varstruct)
68 ; CHECK: add x8, {{x[0-9]+}}, {{#?}}:lo12:varstruct
6969 ; CHECK: bl return_large_struct
7070
7171 ret void
127127 call void @check_i128_stackalign(i32 0, i32 1, i32 2, i32 3,
128128 i32 4, i32 5, i32 6, i32 7,
129129 i32 42, i128 %val)
130 ; CHECK: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
131 ; CHECK: ldp [[I128LO:x[0-9]+]], [[I128HI:x[0-9]+]], [x[[VAR128]]]
130 ; CHECK: ldr [[I128LO:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128]
131 ; CHECK: ldr [[I128HI:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128+8]
132132 ; CHECK: stp [[I128HI]], {{x[0-9]+}}, [sp, #24]
133133
134 ; CHECK-NONEON: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
135 ; CHECK-NONEON: ldp [[I128LO:x[0-9]+]], [[I128HI:x[0-9]+]], [x[[VAR128]]]
134 ; CHECK-NONEON: ldr [[I128LO:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128]
135 ; CHECK-NONEON: ldr [[I128HI:x[0-9]+]], [{{x[0-9]+}}, :lo12:var128+8]
136136 ; CHECK-NONEON: stp [[I128HI]], {{x[0-9]+}}, [sp, #24]
137137 ; CHECK: bl check_i128_stackalign
138138
6666 ; CHECK-LABEL: ldst_64bit:
6767 ; CHECK: adrp [[RL:x[0-9]+]], var_64bit
6868 ; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[RL]], {{#?}}:lo12:var_64bit{{\]}}
69 ; CHECK: adrp [[RQ:x[0-9]+]], var_128bit
70 ; CHECK-NEXT: add {{x[0-9]+}}, [[RQ]], {{#?}}:lo12:var_128bit
69 ; CHECK: adrp [[RQ1:x[0-9]+]], var_128bit
70 ; CHECK-NEXT: str {{x[0-9]+}}, {{\[}}[[RQ1]], {{#?}}:lo12:var_128bit{{\]}}
71 ; CHECK: adrp [[RQ2:x[0-9]+]], var_128bit+8
72 ; CHECK-NEXT: str {{x[0-9]+}}, {{\[}}[[RQ2]], {{#?}}:lo12:var_128bit+8{{\]}}
7173 }
7274
7375 define void @ldst_half() {