Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -disable-post-ra < %s | FileCheck %s
      2 ; RUN: llc -verify-machineinstrs -mtriple=arm64-apple-ios -disable-fp-elim -disable-post-ra < %s | FileCheck %s --check-prefix=CHECK-MACHO
      3 
      4 ; This test aims to check basic correctness of frame layout &
      5 ; frame access code. There are 8 functions in this test file,
      6 ; each function implements one element in the cartesian product
      7 ; of:
      8 ; . a function having a VLA/noVLA
      9 ; . a function with dynamic stack realignment/no dynamic stack realignment.
     10 ; . a function needing a frame pionter/no frame pointer,
     11 ; since the presence/absence of these has influence on the frame
     12 ; layout and which pointer to use to access various part of the
     13 ; frame (bp,sp,fp).
     14 ;
     15 ; Furthermore: in every test function:
     16 ; . there is always one integer and 1 floating point argument to be able
     17 ;   to check those are accessed correctly.
     18 ; . there is always one local variable to check that is accessed
     19 ;   correctly
     20 ;
     21 ; The LLVM-IR below was produced by clang on the following C++ code:
     22 ;extern "C" int g();
     23 ;extern "C" int novla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     24 ;                                             double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     25 ;{
     26 ;  // use an argument passed on the stack.
     27 ;  volatile int l1;
     28 ;  return i10 + (int)d10 + l1 + g();
     29 ;}
     30 ;extern "C" int novla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     31 ;                                             double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     32 ;{
     33 ;  // use an argument passed on the stack.
     34 ;  volatile int l1;
     35 ;  return i10 + (int)d10 + l1;
     36 ;}
     37 ;extern "C" int novla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     38 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     39 ;{
     40 ;  // use an argument passed on the stack.
     41 ;  alignas(128) volatile int l1;
     42 ;  return i10 + (int)d10 + l1 + g();
     43 ;}
     44 ;extern "C" int novla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     45 ;                                           double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     46 ;{
     47 ;  // use an argument passed on the stack.
     48 ;  alignas(128) volatile int l1;
     49 ;  return i10 + (int)d10 + l1;
     50 ;}
     51 ;
     52 ;extern "C" int vla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     53 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     54 ;{
     55 ;  // use an argument passed on the stack.
     56 ;  volatile int l1;
     57 ;  volatile int vla[i1];
     58 ;  return i10 + (int)d10 + l1 + g() + vla[0];
     59 ;}
     60 ;extern "C" int vla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     61 ;                                           double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     62 ;{
     63 ;  // use an argument passed on the stack.
     64 ;  volatile int l1;
     65 ;  volatile int vla[i1];
     66 ;  return i10 + (int)d10 + l1 + vla[0];
     67 ;}
     68 ;extern "C" int vla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     69 ;                                       double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     70 ;{
     71 ;  // use an argument passed on the stack.
     72 ;  alignas(128) volatile int l1;
     73 ;  volatile int vla[i1];
     74 ;  return i10 + (int)d10 + l1 + g() + vla[0];
     75 ;}
     76 ;extern "C" int vla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
     77 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
     78 ;{
     79 ;  // use an argument passed on the stack.
     80 ;  alignas(128) volatile int l1;
     81 ;  volatile int vla[i1];
     82 ;  return i10 + (int)d10 + l1 + vla[0];
     83 ;}
     84 
     85 
     86 
     87 define i32 @novla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
     88 entry:
     89   %l1 = alloca i32, align 4
     90   %conv = fptosi double %d10 to i32
     91   %add = add nsw i32 %conv, %i10
     92   %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
     93   %add1 = add nsw i32 %add, %l1.0.l1.0.
     94   %call = tail call i32 @g()
     95   %add2 = add nsw i32 %add1, %call
     96   ret i32 %add2
     97 }
     98 ; CHECK-LABEL: novla_nodynamicrealign_call
     99 ; CHECK: .cfi_startproc
    100 ;   Check that used callee-saved registers are saved
    101 ; CHECK: sub	sp, sp, #32
    102 ; CHECK: stp	x19, x30, [sp, #16]
    103 ;   Check correctness of cfi pseudo-instructions
    104 ; CHECK: .cfi_def_cfa_offset 32
    105 ; CHECK: .cfi_offset w30, -8
    106 ; CHECK: .cfi_offset w19, -16
    107 ;   Check correct access to arguments passed on the stack, through stack pointer
    108 ; CHECK: ldr	d[[DARG:[0-9]+]], [sp, #56]
    109 ; CHECK: ldr	w[[IARG:[0-9]+]], [sp, #40]
    110 ;   Check correct access to local variable on the stack, through stack pointer
    111 ; CHECK: ldr	w[[ILOC:[0-9]+]], [sp, #12]
    112 ;   Check epilogue:
    113 ; CHECK: ldp	x19, x30, [sp, #16]
    114 ; CHECK: ret
    115 ; CHECK: .cfi_endproc
    116 
    117 ; CHECK-MACHO-LABEL: _novla_nodynamicrealign_call:
    118 ; CHECK-MACHO: .cfi_startproc
    119 ;   Check that used callee-saved registers are saved
    120 ; CHECK-MACHO: sub	sp, sp, #48
    121 ; CHECK-MACHO: stp	x20, x19, [sp, #16]
    122 ;   Check that the frame pointer is created:
    123 ; CHECK-MACHO: stp	x29, x30, [sp, #32]
    124 ; CHECK-MACHO: add	x29, sp, #32
    125 ;   Check correctness of cfi pseudo-instructions
    126 ; CHECK-MACHO: .cfi_def_cfa w29, 16
    127 ; CHECK-MACHO: .cfi_offset w30, -8
    128 ; CHECK-MACHO: .cfi_offset w29, -16
    129 ; CHECK-MACHO: .cfi_offset w19, -24
    130 ; CHECK-MACHO: .cfi_offset w20, -32
    131 ;   Check correct access to arguments passed on the stack, through frame pointer
    132 ; CHECK-MACHO: ldr	d[[DARG:[0-9]+]], [x29, #32]
    133 ; CHECK-MACHO: ldr	w[[IARG:[0-9]+]], [x29, #20]
    134 ;   Check correct access to local variable on the stack, through stack pointer
    135 ; CHECK-MACHO: ldr	w[[ILOC:[0-9]+]], [sp, #12]
    136 ;   Check epilogue:
    137 ; CHECK-MACHO: ldp	x29, x30, [sp, #32]
    138 ; CHECK-MACHO: ldp	x20, x19, [sp, #16]
    139 ; CHECK-MACHO: ret
    140 ; CHECK-MACHO: .cfi_endproc
    141 
    142 
    143 declare i32 @g() #0
    144 
    145 ; Function Attrs: nounwind
    146 define i32 @novla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
    147 entry:
    148   %l1 = alloca i32, align 4
    149   %conv = fptosi double %d10 to i32
    150   %add = add nsw i32 %conv, %i10
    151   %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
    152   %add1 = add nsw i32 %add, %l1.0.l1.0.
    153   ret i32 %add1
    154 }
    155 ; CHECK-LABEL: novla_nodynamicrealign_nocall
    156 ;   Check that space is reserved for one local variable on the stack.
    157 ; CHECK:	sub	sp, sp, #16             // =16
    158 ;   Check correct access to arguments passed on the stack, through stack pointer
    159 ; CHECK: ldr	d[[DARG:[0-9]+]], [sp, #40]
    160 ; CHECK: ldr	w[[IARG:[0-9]+]], [sp, #24]
    161 ;   Check correct access to local variable on the stack, through stack pointer
    162 ; CHECK: ldr	w[[ILOC:[0-9]+]], [sp, #12]
    163 ;   Check epilogue:
    164 ; CHECK: add	sp, sp, #16             // =16
    165 ; CHECK: ret
    166 
    167 
    168 define i32 @novla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
    169 entry:
    170   %l1 = alloca i32, align 128
    171   %conv = fptosi double %d10 to i32
    172   %add = add nsw i32 %conv, %i10
    173   %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
    174   %add1 = add nsw i32 %add, %l1.0.l1.0.
    175   %call = tail call i32 @g()
    176   %add2 = add nsw i32 %add1, %call
    177   ret i32 %add2
    178 }
    179 
    180 ; CHECK-LABEL: novla_dynamicrealign_call
    181 ; CHECK: .cfi_startproc
    182 ;   Check that used callee-saved registers are saved
    183 ; CHECK: str	x19, [sp, #-32]!
    184 ;   Check that the frame pointer is created:
    185 ; CHECK: stp	x29, x30, [sp, #16]
    186 ; CHECK: add	x29, sp, #16
    187 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
    188 ; CHECK: sub	x9, sp, #96
    189 ; CHECK: and	sp, x9, #0xffffffffffffff80
    190 ;   Check correctness of cfi pseudo-instructions
    191 ; CHECK: .cfi_def_cfa w29, 16
    192 ; CHECK: .cfi_offset w30, -8
    193 ; CHECK: .cfi_offset w29, -16
    194 ; CHECK: .cfi_offset w19, -32
    195 ;   Check correct access to arguments passed on the stack, through frame pointer
    196 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    197 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    198 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
    199 ; CHECK: ldr	w[[ILOC:[0-9]+]], [sp]
    200 ;   Check epilogue:
    201 ;     Check that stack pointer get restored from frame pointer.
    202 ; CHECK: sub	sp, x29, #16            // =16
    203 ; CHECK: ldp	x29, x30, [sp, #16]
    204 ; CHECK: ldr	x19, [sp], #32
    205 ; CHECK: ret
    206 ; CHECK: .cfi_endproc
    207 
    208 ; CHECK-MACHO-LABEL: _novla_dynamicrealign_call:
    209 ; CHECK-MACHO: .cfi_startproc
    210 ;   Check that used callee-saved registers are saved
    211 ; CHECK-MACHO: stp	x20, x19, [sp, #-32]!
    212 ;   Check that the frame pointer is created:
    213 ; CHECK-MACHO: stp	x29, x30, [sp, #16]
    214 ; CHECK-MACHO: add	x29, sp, #16
    215 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
    216 ; CHECK-MACHO: sub	x9, sp, #96
    217 ; CHECK-MACHO: and	sp, x9, #0xffffffffffffff80
    218 ;   Check correctness of cfi pseudo-instructions
    219 ; CHECK-MACHO: .cfi_def_cfa w29, 16
    220 ; CHECK-MACHO: .cfi_offset w30, -8
    221 ; CHECK-MACHO: .cfi_offset w29, -16
    222 ; CHECK-MACHO: .cfi_offset w19, -24
    223 ; CHECK-MACHO: .cfi_offset w20, -32
    224 ;   Check correct access to arguments passed on the stack, through frame pointer
    225 ; CHECK-MACHO: ldr	d[[DARG:[0-9]+]], [x29, #32]
    226 ; CHECK-MACHO: ldr	w[[IARG:[0-9]+]], [x29, #20]
    227 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
    228 ; CHECK-MACHO: ldr	w[[ILOC:[0-9]+]], [sp]
    229 ;   Check epilogue:
    230 ;     Check that stack pointer get restored from frame pointer.
    231 ; CHECK-MACHO: sub	sp, x29, #16
    232 ; CHECK-MACHO: ldp	x29, x30, [sp, #16]
    233 ; CHECK-MACHO: ldp	x20, x19, [sp], #32
    234 ; CHECK-MACHO: ret
    235 ; CHECK-MACHO: .cfi_endproc
    236 
    237 
    238 ; Function Attrs: nounwind
    239 define i32 @novla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
    240 entry:
    241   %l1 = alloca i32, align 128
    242   %conv = fptosi double %d10 to i32
    243   %add = add nsw i32 %conv, %i10
    244   %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
    245   %add1 = add nsw i32 %add, %l1.0.l1.0.
    246   ret i32 %add1
    247 }
    248 
    249 ; CHECK-LABEL: novla_dynamicrealign_nocall
    250 ;   Check that the frame pointer is created:
    251 ; CHECK: stp	x29, x30, [sp, #-16]!
    252 ; CHECK: mov	x29, sp
    253 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
    254 ; CHECK: sub	x9, sp, #112
    255 ; CHECK: and	sp, x9, #0xffffffffffffff80
    256 ;   Check correct access to arguments passed on the stack, through frame pointer
    257 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    258 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    259 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
    260 ; CHECK: ldr	w[[ILOC:[0-9]+]], [sp]
    261 ;   Check epilogue:
    262 ;     Check that stack pointer get restored from frame pointer.
    263 ; CHECK: mov	sp, x29
    264 ; CHECK: ldp	x29, x30, [sp], #16
    265 ; CHECK: ret
    266 
    267 
    268 define i32 @vla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
    269 entry:
    270   %l1 = alloca i32, align 4
    271   %0 = zext i32 %i1 to i64
    272   %vla = alloca i32, i64 %0, align 4
    273   %conv = fptosi double %d10 to i32
    274   %add = add nsw i32 %conv, %i10
    275   %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
    276   %add1 = add nsw i32 %add, %l1.0.l1.0.
    277   %call = tail call i32 @g()
    278   %add2 = add nsw i32 %add1, %call
    279   %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
    280   %add3 = add nsw i32 %add2, %1
    281   ret i32 %add3
    282 }
    283 
    284 ; CHECK-LABEL: vla_nodynamicrealign_call
    285 ; CHECK: .cfi_startproc
    286 ;   Check that used callee-saved registers are saved
    287 ; CHECK: stp	x20, x19, [sp, #-32]!
    288 ;   Check that the frame pointer is created:
    289 ; CHECK: stp	x29, x30, [sp, #16]
    290 ; CHECK: add	x29, sp, #16
    291 ;   Check that space is reserved on the stack for the local variable,
    292 ;   rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
    293 ; CHECK: sub	sp, sp, #16
    294 ;   Check correctness of cfi pseudo-instructions
    295 ; CHECK: .cfi_def_cfa w29, 16
    296 ; CHECK: .cfi_offset w30, -8
    297 ; CHECK: .cfi_offset w29, -16
    298 ; CHECK: .cfi_offset w19, -24
    299 ; CHECK: .cfi_offset w20, -32
    300 ;   Check correct access to arguments passed on the stack, through frame pointer
    301 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    302 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    303 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    304 ; CHECK: mov	w9, w0
    305 ; CHECK: mov	 x10, sp
    306 ; CHECK: lsl	x9, x9, #2
    307 ; CHECK: add	x9, x9, #15
    308 ; CHECK: and	x9, x9, #0x7fffffff0
    309 ; CHECK: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    310 ; CHECK: mov	 sp, x[[VLASPTMP]]
    311 ;   Check correct access to local variable, through frame pointer
    312 ; CHECK: ldur	w[[ILOC:[0-9]+]], [x29, #-20]
    313 ;   Check correct accessing of the VLA variable through the base pointer
    314 ; CHECK: ldr	w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    315 ;   Check epilogue:
    316 ;     Check that stack pointer get restored from frame pointer.
    317 ; CHECK: sub	sp, x29, #16            // =16
    318 ; CHECK: ldp	x29, x30, [sp, #16]
    319 ; CHECK: ldp	x20, x19, [sp], #32
    320 ; CHECK: ret
    321 ; CHECK: .cfi_endproc
    322 
    323 
    324 ; Function Attrs: nounwind
    325 define i32 @vla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
    326 entry:
    327   %l1 = alloca i32, align 4
    328   %0 = zext i32 %i1 to i64
    329   %vla = alloca i32, i64 %0, align 4
    330   %conv = fptosi double %d10 to i32
    331   %add = add nsw i32 %conv, %i10
    332   %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
    333   %add1 = add nsw i32 %add, %l1.0.l1.0.
    334   %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
    335   %add2 = add nsw i32 %add1, %1
    336   ret i32 %add2
    337 }
    338 
    339 ; CHECK-LABEL: vla_nodynamicrealign_nocall
    340 ;   Check that the frame pointer is created:
    341 ; CHECK: stp	x29, x30, [sp, #-16]!
    342 ; CHECK: mov	x29, sp
    343 ;   Check that space is reserved on the stack for the local variable,
    344 ;   rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
    345 ; CHECK: sub	sp, sp, #16
    346 ;   Check correctness of cfi pseudo-instructions
    347 ;   Check correct access to arguments passed on the stack, through frame pointer
    348 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    349 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    350 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    351 ; CHECK: mov	w9, w0
    352 ; CHECK: mov	 x10, sp
    353 ; CHECK: lsl	x9, x9, #2
    354 ; CHECK: add	x9, x9, #15
    355 ; CHECK: and	x9, x9, #0x7fffffff0
    356 ; CHECK: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    357 ; CHECK: mov	 sp, x[[VLASPTMP]]
    358 ;   Check correct access to local variable, through frame pointer
    359 ; CHECK: ldur	w[[ILOC:[0-9]+]], [x29, #-4]
    360 ;   Check correct accessing of the VLA variable through the base pointer
    361 ; CHECK: ldr	w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    362 ;   Check epilogue:
    363 ;     Check that stack pointer get restored from frame pointer.
    364 ; CHECK: mov    sp, x29
    365 ; CHECK: ldp	x29, x30, [sp], #16
    366 ; CHECK: ret
    367 
    368 
    369 define i32 @vla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
    370 entry:
    371   %l1 = alloca i32, align 128
    372   %0 = zext i32 %i1 to i64
    373   %vla = alloca i32, i64 %0, align 4
    374   %conv = fptosi double %d10 to i32
    375   %add = add nsw i32 %conv, %i10
    376   %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
    377   %add1 = add nsw i32 %add, %l1.0.l1.0.
    378   %call = tail call i32 @g()
    379   %add2 = add nsw i32 %add1, %call
    380   %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
    381   %add3 = add nsw i32 %add2, %1
    382   ret i32 %add3
    383 }
    384 
    385 ; CHECK-LABEL: vla_dynamicrealign_call
    386 ; CHECK: .cfi_startproc
    387 ;   Check that used callee-saved registers are saved
    388 ; CHECK: str	x21, [sp, #-48]!
    389 ; CHECK: stp	x20, x19, [sp, #16]
    390 ;   Check that the frame pointer is created:
    391 ; CHECK: stp	x29, x30, [sp, #32]
    392 ; CHECK: add	x29, sp, #32
    393 ;   Check that the stack pointer gets re-aligned to 128
    394 ;   bytes & the base pointer (x19) gets initialized to
    395 ;   this 128-byte aligned area for local variables &
    396 ;   spill slots
    397 ; CHECK: sub	x9, sp, #80            // =80
    398 ; CHECK: and	sp, x9, #0xffffffffffffff80
    399 ; CHECK: mov    x19, sp
    400 ;   Check correctness of cfi pseudo-instructions
    401 ; CHECK: .cfi_def_cfa w29, 16
    402 ; CHECK: .cfi_offset w30, -8
    403 ; CHECK: .cfi_offset w29, -16
    404 ; CHECK: .cfi_offset w19, -24
    405 ; CHECK: .cfi_offset w20, -32
    406 ; CHECK: .cfi_offset w21, -48
    407 ;   Check correct access to arguments passed on the stack, through frame pointer
    408 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    409 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    410 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    411 ;   and set-up of base pointer (x19).
    412 ; CHECK: mov	w9, w0
    413 ; CHECK: mov	 x10, sp
    414 ; CHECK: lsl	x9, x9, #2
    415 ; CHECK: add	x9, x9, #15
    416 ; CHECK: and	x9, x9, #0x7fffffff0
    417 ; CHECK: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    418 ; CHECK: mov	 sp, x[[VLASPTMP]]
    419 ;   Check correct access to local variable, through base pointer
    420 ; CHECK: ldr	w[[ILOC:[0-9]+]], [x19]
    421 ; CHECK: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    422 ;   Check epilogue:
    423 ;     Check that stack pointer get restored from frame pointer.
    424 ; CHECK: sub	sp, x29, #32
    425 ; CHECK: ldp	x29, x30, [sp, #32]
    426 ; CHECK: ldp	x20, x19, [sp, #16]
    427 ; CHECK: ldr	x21, [sp], #48
    428 ; CHECK: ret
    429 ; CHECK: .cfi_endproc
    430 
    431 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_call:
    432 ; CHECK-MACHO: .cfi_startproc
    433 ;   Check that used callee-saved registers are saved
    434 ; CHECK-MACHO: stp	x22, x21, [sp, #-48]!
    435 ; CHECK-MACHO: stp	x20, x19, [sp, #16]
    436 ;   Check that the frame pointer is created:
    437 ; CHECK-MACHO: stp	x29, x30, [sp, #32]
    438 ; CHECK-MACHO: add	x29, sp, #32
    439 ;   Check that the stack pointer gets re-aligned to 128
    440 ;   bytes & the base pointer (x19) gets initialized to
    441 ;   this 128-byte aligned area for local variables &
    442 ;   spill slots
    443 ; CHECK-MACHO: sub	x9, sp, #80
    444 ; CHECK-MACHO: and	sp, x9, #0xffffffffffffff80
    445 ; CHECK-MACHO: mov    x19, sp
    446 ;   Check correctness of cfi pseudo-instructions
    447 ; CHECK-MACHO: .cfi_def_cfa w29, 16
    448 ; CHECK-MACHO: .cfi_offset w30, -8
    449 ; CHECK-MACHO: .cfi_offset w29, -16
    450 ; CHECK-MACHO: .cfi_offset w19, -24
    451 ; CHECK-MACHO: .cfi_offset w20, -32
    452 ; CHECK-MACHO: .cfi_offset w21, -40
    453 ; CHECK-MACHO: .cfi_offset w22, -48
    454 ;   Check correct access to arguments passed on the stack, through frame pointer
    455 ; CHECK-MACHO: ldr	w[[IARG:[0-9]+]], [x29, #20]
    456 ; CHECK-MACHO: ldr	d[[DARG:[0-9]+]], [x29, #32]
    457 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    458 ;   and set-up of base pointer (x19).
    459 ; CHECK-MACHO: mov	w9, w0
    460 ; CHECK-MACHO: mov	 x10, sp
    461 ; CHECK-MACHO: lsl	x9, x9, #2
    462 ; CHECK-MACHO: add	x9, x9, #15
    463 ; CHECK-MACHO: and	x9, x9, #0x7fffffff0
    464 ; CHECK-MACHO: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    465 ; CHECK-MACHO: mov	 sp, x[[VLASPTMP]]
    466 ;   Check correct access to local variable, through base pointer
    467 ; CHECK-MACHO: ldr	w[[ILOC:[0-9]+]], [x19]
    468 ; CHECK-MACHO: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    469 ;   Check epilogue:
    470 ;     Check that stack pointer get restored from frame pointer.
    471 ; CHECK-MACHO: sub	sp, x29, #32
    472 ; CHECK-MACHO: ldp	x29, x30, [sp, #32]
    473 ; CHECK-MACHO: ldp	x20, x19, [sp, #16]
    474 ; CHECK-MACHO: ldp	x22, x21, [sp], #48
    475 ; CHECK-MACHO: ret
    476 ; CHECK-MACHO: .cfi_endproc
    477 
    478 
    479 ; Function Attrs: nounwind
    480 define i32 @vla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
    481 entry:
    482   %l1 = alloca i32, align 128
    483   %0 = zext i32 %i1 to i64
    484   %vla = alloca i32, i64 %0, align 4
    485   %conv = fptosi double %d10 to i32
    486   %add = add nsw i32 %conv, %i10
    487   %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
    488   %add1 = add nsw i32 %add, %l1.0.l1.0.
    489   %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
    490   %add2 = add nsw i32 %add1, %1
    491   ret i32 %add2
    492 }
    493 
    494 ; CHECK-LABEL: vla_dynamicrealign_nocall
    495 ;   Check that used callee-saved registers are saved
    496 ; CHECK: str	x19, [sp, #-32]!
    497 ;   Check that the frame pointer is created:
    498 ; CHECK: stp	x29, x30, [sp, #16]
    499 ; CHECK: add	x29, sp, #16
    500 ;   Check that the stack pointer gets re-aligned to 128
    501 ;   bytes & the base pointer (x19) gets initialized to
    502 ;   this 128-byte aligned area for local variables &
    503 ;   spill slots
    504 ; CHECK: sub	x9, sp, #96
    505 ; CHECK: and	sp, x9, #0xffffffffffffff80
    506 ; CHECK: mov    x19, sp
    507 ;   Check correct access to arguments passed on the stack, through frame pointer
    508 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    509 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    510 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    511 ;   and set-up of base pointer (x19).
    512 ; CHECK: mov	w9, w0
    513 ; CHECK: mov	 x10, sp
    514 ; CHECK: lsl	x9, x9, #2
    515 ; CHECK: add	x9, x9, #15
    516 ; CHECK: and	x9, x9, #0x7fffffff0
    517 ; CHECK: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    518 ; CHECK: mov	 sp, x[[VLASPTMP]]
    519 ;   Check correct access to local variable, through base pointer
    520 ; CHECK: ldr	w[[ILOC:[0-9]+]], [x19]
    521 ; CHECK: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    522 ;   Check epilogue:
    523 ;     Check that stack pointer get restored from frame pointer.
    524 ; CHECK: sub	sp, x29, #16
    525 ; CHECK: ldp	x29, x30, [sp, #16]
    526 ; CHECK: ldr	x19, [sp], #32
    527 ; CHECK: ret
    528 
    529 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:
    530 ;   Check that used callee-saved registers are saved
    531 ; CHECK-MACHO: stp	x20, x19, [sp, #-32]!
    532 ;   Check that the frame pointer is created:
    533 ; CHECK-MACHO: stp	x29, x30, [sp, #16]
    534 ; CHECK-MACHO: add	x29, sp, #16
    535 ;   Check that the stack pointer gets re-aligned to 128
    536 ;   bytes & the base pointer (x19) gets initialized to
    537 ;   this 128-byte aligned area for local variables &
    538 ;   spill slots
    539 ; CHECK-MACHO: sub	x9, sp, #96
    540 ; CHECK-MACHO: and	sp, x9, #0xffffffffffffff80
    541 ; CHECK-MACHO: mov    x19, sp
    542 ;   Check correct access to arguments passed on the stack, through frame pointer
    543 ; CHECK-MACHO: ldr	w[[IARG:[0-9]+]], [x29, #20]
    544 ; CHECK-MACHO: ldr	d[[DARG:[0-9]+]], [x29, #32]
    545 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    546 ;   and set-up of base pointer (x19).
    547 ; CHECK-MACHO: mov	w9, w0
    548 ; CHECK-MACHO: mov	 x10, sp
    549 ; CHECK-MACHO: lsl	x9, x9, #2
    550 ; CHECK-MACHO: add	x9, x9, #15
    551 ; CHECK-MACHO: and	x9, x9, #0x7fffffff0
    552 ; CHECK-MACHO: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    553 ; CHECK-MACHO: mov	 sp, x[[VLASPTMP]]
    554 ;   Check correct access to local variable, through base pointer
    555 ; CHECK-MACHO: ldr	w[[ILOC:[0-9]+]], [x19]
    556 ; CHECK-MACHO: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    557 ;   Check epilogue:
    558 ;     Check that stack pointer get restored from frame pointer.
    559 ; CHECK-MACHO: sub	sp, x29, #16
    560 ; CHECK-MACHO: ldp	x29, x30, [sp, #16]
    561 ; CHECK-MACHO: ldp	x20, x19, [sp], #32
    562 ; CHECK-MACHO: ret
    563 
    564 
    565 ; Function Attrs: nounwind
    566 define i32 @vla_dynamicrealign_nocall_large_align(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
    567 entry:
    568   %l1 = alloca i32, align 32768
    569   %0 = zext i32 %i1 to i64
    570   %vla = alloca i32, i64 %0, align 4
    571   %conv = fptosi double %d10 to i32
    572   %add = add nsw i32 %conv, %i10
    573   %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768
    574   %add1 = add nsw i32 %add, %l1.0.l1.0.
    575   %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
    576   %add2 = add nsw i32 %add1, %1
    577   ret i32 %add2
    578 }
    579 
    580 ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
    581 ;   Check that used callee-saved registers are saved
    582 ; CHECK: stp	x28, x19, [sp, #-32]!
    583 ;   Check that the frame pointer is created:
    584 ; CHECK: stp	x29, x30, [sp, #16]
    585 ; CHECK: add	x29, sp, #16
    586 ;   Check that the stack pointer gets re-aligned to 128
    587 ;   bytes & the base pointer (x19) gets initialized to
    588 ;   this 128-byte aligned area for local variables &
    589 ;   spill slots
    590 ; CHECK: sub	x9, sp, #7, lsl #12
    591 ; CHECK: and	sp, x9, #0xffffffffffff8000
    592 ; CHECK: mov    x19, sp
    593 ;   Check correct access to arguments passed on the stack, through frame pointer
    594 ; CHECK: ldr	w[[IARG:[0-9]+]], [x29, #24]
    595 ; CHECK: ldr	d[[DARG:[0-9]+]], [x29, #40]
    596 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    597 ;   and set-up of base pointer (x19).
    598 ; CHECK: mov	w9, w0
    599 ; CHECK: mov	 x10, sp
    600 ; CHECK: lsl	x9, x9, #2
    601 ; CHECK: add	x9, x9, #15
    602 ; CHECK: and	x9, x9, #0x7fffffff0
    603 ; CHECK: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    604 ; CHECK: mov	 sp, x[[VLASPTMP]]
    605 ;   Check correct access to local variable, through base pointer
    606 ; CHECK: ldr	w[[ILOC:[0-9]+]], [x19]
    607 ; CHECK: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    608 ;   Check epilogue:
    609 ;     Check that stack pointer get restored from frame pointer.
    610 ; CHECK: sub	sp, x29, #16
    611 ; CHECK: ldp	x29, x30, [sp, #16]
    612 ; CHECK: ldp	x28, x19, [sp], #32
    613 ; CHECK: ret
    614 
    615 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:
    616 ;   Check that used callee-saved registers are saved
    617 ; CHECK-MACHO: stp	x20, x19, [sp, #-32]!
    618 ;   Check that the frame pointer is created:
    619 ; CHECK-MACHO: stp	x29, x30, [sp, #16]
    620 ; CHECK-MACHO: add	x29, sp, #16
    621 ;   Check that the stack pointer gets re-aligned to 128
    622 ;   bytes & the base pointer (x19) gets initialized to
    623 ;   this 128-byte aligned area for local variables &
    624 ;   spill slots
    625 ; CHECK-MACHO: sub	x9, sp, #7, lsl #12
    626 ; CHECK-MACHO: and	sp, x9, #0xffffffffffff8000
    627 ; CHECK-MACHO: mov    x19, sp
    628 ;   Check correct access to arguments passed on the stack, through frame pointer
    629 ; CHECK-MACHO: ldr	w[[IARG:[0-9]+]], [x29, #20]
    630 ; CHECK-MACHO: ldr	d[[DARG:[0-9]+]], [x29, #32]
    631 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
    632 ;   and set-up of base pointer (x19).
    633 ; CHECK-MACHO: mov	w9, w0
    634 ; CHECK-MACHO: mov	 x10, sp
    635 ; CHECK-MACHO: lsl	x9, x9, #2
    636 ; CHECK-MACHO: add	x9, x9, #15
    637 ; CHECK-MACHO: and	x9, x9, #0x7fffffff0
    638 ; CHECK-MACHO: sub	 x[[VLASPTMP:[0-9]+]], x10, x9
    639 ; CHECK-MACHO: mov	 sp, x[[VLASPTMP]]
    640 ;   Check correct access to local variable, through base pointer
    641 ; CHECK-MACHO: ldr	w[[ILOC:[0-9]+]], [x19]
    642 ; CHECK-MACHO: ldr	 w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
    643 ;   Check epilogue:
    644 ;     Check that stack pointer get restored from frame pointer.
    645 ; CHECK-MACHO: sub	sp, x29, #16
    646 ; CHECK-MACHO: ldp	x29, x30, [sp, #16]
    647 ; CHECK-MACHO: ldp	x20, x19, [sp], #32
    648 ; CHECK-MACHO: ret
    649 
    650 
    651 define void @realign_conditional(i1 %b) {
    652 entry:
    653   br i1 %b, label %bb0, label %bb1
    654 
    655 bb0:
    656   %MyAlloca = alloca i8, i64 64, align 32
    657   br label %bb1
    658 
    659 bb1:
    660   ret void
    661 }
    662 
    663 ; CHECK-LABEL: realign_conditional
    664 ; No realignment in the prologue.
    665 ; CHECK-NOT:  and
    666 ; CHECK-NOT:  0xffffffffffffffe0
    667 ; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
    668 ; Stack is realigned in a non-entry BB.
    669 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
    670 ; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
    671 ; CHECK:  .[[LABEL]]:
    672 ; CHECK:  ret
    673 
    674 
    675 define void @realign_conditional2(i1 %b) {
    676 entry:
    677   %tmp = alloca i8, i32 16
    678   br i1 %b, label %bb0, label %bb1
    679 
    680 bb0:
    681   %MyAlloca = alloca i8, i64 64, align 32
    682   br label %bb1
    683 
    684 bb1:
    685   ret void
    686 }
    687 
    688 ; CHECK-LABEL: realign_conditional2
    689 ; Extra realignment in the prologue (performance issue).
    690 ; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
    691 ; CHECK:  sub  x9, sp, #32            // =32
    692 ; CHECK:  and  sp, x9, #0xffffffffffffffe0
    693 ; CHECK:  mov   x19, sp
    694 ; Stack is realigned in a non-entry BB.
    695 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
    696 ; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
    697 ; CHECK:  .[[LABEL]]:
    698 ; CHECK:  ret
    699 
    700 attributes #0 = { "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
    701 attributes #1 = { nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
    702 
    703 !1 = !{!2, !2, i64 0}
    704 !2 = !{!"int", !3, i64 0}
    705 !3 = !{!"omnipotent char", !4, i64 0}
    706 !4 = !{!"Simple C/C++ TBAA"}
    707