1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc < %s -mtriple=armv7-none-eabi -O0 | FileCheck %s --check-prefix=CHECK --check-prefix=LE 3; RUN: llc < %s -mtriple=armv7eb-none-eabi -O0 | FileCheck %s --check-prefix=CHECK --check-prefix=BE 4 5;; Previously, this failed during register allocation because the CMP_SWAP_64 6;; pseudo-instruction has a lot of operands, many of which need to be even-odd 7;; register pairs, and the over-aligned alloca in this function causes both a 8;; frame pointer and a base pointer to be needed. 9 10define void @test(ptr %ptr) { 11; CHECK-LABEL: test: 12; CHECK: @ %bb.0: @ %entry 13; CHECK-NEXT: .save {r4, r5, r6, r8, r9, r10, r11, lr} 14; CHECK-NEXT: push {r4, r5, r6, r8, r9, r10, r11, lr} 15; CHECK-NEXT: .setfp r11, sp, #24 16; CHECK-NEXT: add r11, sp, #24 17; CHECK-NEXT: .pad #32 18; CHECK-NEXT: sub sp, sp, #32 19; CHECK-NEXT: bfc sp, #0, #4 20; CHECK-NEXT: mov r6, sp 21; CHECK-NEXT: str r0, [r6, #28] @ 4-byte Spill 22; CHECK-NEXT: b .LBB0_1 23; CHECK-NEXT: .LBB0_1: @ %block1 24; CHECK-NEXT: ldr r0, [r6, #28] @ 4-byte Reload 25; CHECK-NEXT: mov r1, sp 26; CHECK-NEXT: sub r1, r1, #16 27; CHECK-NEXT: bic r1, r1, #15 28; CHECK-NEXT: mov sp, r1 29; CHECK-NEXT: dmb ish 30; CHECK-NEXT: ldr r1, [r0] 31; CHECK-NEXT: ldr r0, [r0, #4] 32; CHECK-NEXT: str r1, [r6, #20] @ 4-byte Spill 33; CHECK-NEXT: str r0, [r6, #24] @ 4-byte Spill 34; CHECK-NEXT: b .LBB0_2 35; CHECK-NEXT: .LBB0_2: @ %atomicrmw.start 36; CHECK-NEXT: @ =>This Loop Header: Depth=1 37; CHECK-NEXT: @ Child Loop BB0_3 Depth 2 38; CHECK-NEXT: ldr r2, [r6, #24] @ 4-byte Reload 39; CHECK-NEXT: ldr r0, [r6, #20] @ 4-byte Reload 40; CHECK-NEXT: ldr r8, [r6, #28] @ 4-byte Reload 41; LE-NEXT: str r2, [r6, #16] @ 4-byte Spill 42; LE-NEXT: str r0, [r6, #12] @ 4-byte Spill 43; BE-NEXT: str r2, [r6, #12] @ 4-byte Spill 44; BE-NEXT: str r0, [r6, #16] @ 4-byte Spill 45; CHECK-NEXT: @ implicit-def: $r1 46; CHECK-NEXT: @ implicit-def: $r3 47; CHECK-NEXT: @ kill: def $r8 killed $r8 def $r8_r9 48; CHECK-NEXT: mov r9, r1 49; CHECK-NEXT: @ kill: def $r0 killed $r0 def $r0_r1 50; CHECK-NEXT: mov r1, r2 51; CHECK-NEXT: mov r12, #0 52; CHECK-NEXT: mov r2, r12 53; CHECK-NEXT: mov r3, r12 54; CHECK-NEXT: .LBB0_3: @ %atomicrmw.start 55; CHECK-NEXT: @ Parent Loop BB0_2 Depth=1 56; CHECK-NEXT: @ => This Inner Loop Header: Depth=2 57; CHECK-NEXT: ldrexd r4, r5, [r8] 58; CHECK-NEXT: cmp r4, r0 59; CHECK-NEXT: cmpeq r5, r1 60; CHECK-NEXT: bne .LBB0_5 61; CHECK-NEXT: @ %bb.4: @ %atomicrmw.start 62; CHECK-NEXT: @ in Loop: Header=BB0_3 Depth=2 63; CHECK-NEXT: strexd r9, r2, r3, [r8] 64; CHECK-NEXT: cmp r9, #0 65; CHECK-NEXT: bne .LBB0_3 66; CHECK-NEXT: .LBB0_5: @ %atomicrmw.start 67; CHECK-NEXT: @ in Loop: Header=BB0_2 Depth=1 68; CHECK-NEXT: ldr r2, [r6, #12] @ 4-byte Reload 69; LE-NEXT: ldr r1, [r6, #16] @ 4-byte Reload 70; LE-NEXT: mov r0, r5 71; LE-NEXT: eor r3, r0, r1 72; LE-NEXT: mov r1, r4 73; LE-NEXT: eor r2, r1, r2 74; BE-NEXT: ldr r0, [r6, #16] @ 4-byte Reload 75; BE-NEXT: mov r1, r4 76; BE-NEXT: eor r3, r1, r0 77; BE-NEXT: mov r0, r5 78; BE-NEXT: eor r2, r0, r2 79; CHECK-NEXT: orr r2, r2, r3 80; CHECK-NEXT: cmp r2, #0 81; CHECK-NEXT: str r1, [r6, #20] @ 4-byte Spill 82; CHECK-NEXT: str r0, [r6, #24] @ 4-byte Spill 83; CHECK-NEXT: bne .LBB0_2 84; CHECK-NEXT: b .LBB0_6 85; CHECK-NEXT: .LBB0_6: @ %atomicrmw.end 86; CHECK-NEXT: dmb ish 87; CHECK-NEXT: sub sp, r11, #24 88; CHECK-NEXT: pop {r4, r5, r6, r8, r9, r10, r11, pc} 89entry: 90 br label %block1 91 92block1: 93 %stuff = alloca i8, i64 16, align 16 94 store atomic i64 0, ptr %ptr seq_cst, align 8 95 ret void 96} 97