diff --git a/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_ints.ll b/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_ints.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_ints.ll @@ -0,0 +1,3615 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; Test the instruction sequences produced by atomicrmw instructions. In +; particular, ensure there are no stores/spills inserted between the exclusive +; load and stores, which would invalidate the exclusive monitor. + +; RUN: llc -mtriple=armv8-none-linux-gnu -O0 -o - %s | FileCheck %s --check-prefix=CHECK-ARM8 +; RUN: llc -mtriple=armv6-none-linux-gnu -O0 -o - %s | FileCheck %s --check-prefix=CHECK-ARM6 +; RUN: llc -mtriple=thumbv7-none-linux-gnu -O0 -o - %s | FileCheck %s --check-prefix=CHECK-THUMB2 +; RUN: llc -mtriple=thumbv6-none-linux-gnu -O0 -o - %s | FileCheck %s --check-prefix=CHECK-THUMB1 + +@atomic_i8 = external global i8 +@atomic_i16 = external global i16 +@atomic_i32 = external global i32 +@atomic_i64 = external global i64 + +define i8 @test_xchg_i8() { +; CHECK-ARM8-LABEL: test_xchg_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB0_1 +; CHECK-ARM8-NEXT: .LBB0_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: mov r1, #1 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB0_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xchg_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB0_1 +; CHECK-ARM6-NEXT: .LBB0_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI0_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI0_0 +; CHECK-ARM6-NEXT: mov r1, #1 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB0_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI0_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_xchg_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB0_1 +; CHECK-THUMB2-NEXT: .LBB0_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB0_1 +; CHECK-THUMB2-NEXT: b .LBB0_2 +; CHECK-THUMB2-NEXT: .LBB0_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xchg_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI0_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_lock_test_and_set_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI0_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw xchg i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_add_i8() { +; CHECK-ARM8-LABEL: test_add_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB1_1 +; CHECK-ARM8-NEXT: .LBB1_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: add r0, r0, r1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB1_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_add_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB1_1 +; CHECK-ARM6-NEXT: .LBB1_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI1_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: add r0, r0, #1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI1_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB1_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI1_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_add_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB1_1 +; CHECK-THUMB2-NEXT: .LBB1_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: adds r1, r0, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB1_1 +; CHECK-THUMB2-NEXT: b .LBB1_2 +; CHECK-THUMB2-NEXT: .LBB1_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_add_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI1_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_add_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI1_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw add i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_sub_i8() { +; CHECK-ARM8-LABEL: test_sub_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB2_1 +; CHECK-ARM8-NEXT: .LBB2_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: sub r0, r0, r1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB2_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_sub_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB2_1 +; CHECK-ARM6-NEXT: .LBB2_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI2_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: sub r0, r0, #1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI2_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB2_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI2_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_sub_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB2_1 +; CHECK-THUMB2-NEXT: .LBB2_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: subs r1, r0, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB2_1 +; CHECK-THUMB2-NEXT: b .LBB2_2 +; CHECK-THUMB2-NEXT: .LBB2_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_sub_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI2_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_sub_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI2_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw sub i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_and_i8() { +; CHECK-ARM8-LABEL: test_and_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB3_1 +; CHECK-ARM8-NEXT: .LBB3_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r0, r0, #1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB3_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_and_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB3_1 +; CHECK-ARM6-NEXT: .LBB3_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI3_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r0, r0, #1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI3_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB3_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI3_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_and_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB3_1 +; CHECK-THUMB2-NEXT: .LBB3_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: and r1, r0, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB3_1 +; CHECK-THUMB2-NEXT: b .LBB3_2 +; CHECK-THUMB2-NEXT: .LBB3_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_and_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI3_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_and_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI3_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw and i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_nand_i8() { +; CHECK-ARM8-LABEL: test_nand_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB4_1 +; CHECK-ARM8-NEXT: .LBB4_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mvn r0, r0 +; CHECK-ARM8-NEXT: mvn r1, #1 +; CHECK-ARM8-NEXT: orr r0, r0, r1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB4_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_nand_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB4_1 +; CHECK-ARM6-NEXT: .LBB4_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI4_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mvn r0, r0 +; CHECK-ARM6-NEXT: mvn r1, #1 +; CHECK-ARM6-NEXT: orr r0, r0, r1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI4_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB4_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI4_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_nand_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB4_1 +; CHECK-THUMB2-NEXT: .LBB4_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r1, [r2] +; CHECK-THUMB2-NEXT: mov r0, r1 +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r0, #254 +; CHECK-THUMB2-NEXT: orn r1, r0, r1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB4_1 +; CHECK-THUMB2-NEXT: b .LBB4_2 +; CHECK-THUMB2-NEXT: .LBB4_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_nand_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI4_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_nand_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI4_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw nand i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_or_i8() { +; CHECK-ARM8-LABEL: test_or_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB5_1 +; CHECK-ARM8-NEXT: .LBB5_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: orr r0, r0, r1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB5_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_or_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB5_1 +; CHECK-ARM6-NEXT: .LBB5_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI5_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: orr r0, r0, #1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI5_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB5_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI5_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_or_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB5_1 +; CHECK-THUMB2-NEXT: .LBB5_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: orr r1, r0, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB5_1 +; CHECK-THUMB2-NEXT: b .LBB5_2 +; CHECK-THUMB2-NEXT: .LBB5_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_or_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI5_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_or_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI5_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw or i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_xor_i8() { +; CHECK-ARM8-LABEL: test_xor_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB6_1 +; CHECK-ARM8-NEXT: .LBB6_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: eor r0, r0, #1 +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB6_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xor_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB6_1 +; CHECK-ARM6-NEXT: .LBB6_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI6_0 +; CHECK-ARM6-NEXT: ldrexb r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: eor r0, r0, #1 +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI6_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB6_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI6_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_xor_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB6_1 +; CHECK-THUMB2-NEXT: .LBB6_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: eor r1, r0, #1 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB6_1 +; CHECK-THUMB2-NEXT: b .LBB6_2 +; CHECK-THUMB2-NEXT: .LBB6_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xor_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI6_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_xor_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI6_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw xor i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_max_i8() { +; CHECK-ARM8-LABEL: test_max_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB7_1 +; CHECK-ARM8-NEXT: .LBB7_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r1, [r0] +; CHECK-ARM8-NEXT: sxtb r2, r1 +; CHECK-ARM8-NEXT: mov r0, r2 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r2, #1 +; CHECK-ARM8-NEXT: movgt r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB7_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_max_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB7_1 +; CHECK-ARM6-NEXT: .LBB7_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI7_0 +; CHECK-ARM6-NEXT: ldrexb r1, [r0] +; CHECK-ARM6-NEXT: sxtb r2, r1 +; CHECK-ARM6-NEXT: mov r0, r2 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r2, #1 +; CHECK-ARM6-NEXT: movgt r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI7_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB7_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI7_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_max_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB7_1 +; CHECK-THUMB2-NEXT: .LBB7_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: sxtb r3, r0 +; CHECK-THUMB2-NEXT: mov r1, r3 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r3, #1 +; CHECK-THUMB2-NEXT: it gt +; CHECK-THUMB2-NEXT: movgt r1, r0 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB7_1 +; CHECK-THUMB2-NEXT: b .LBB7_2 +; CHECK-THUMB2-NEXT: .LBB7_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_max_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI7_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_max_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI7_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw max i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_min_i8() { +; CHECK-ARM8-LABEL: test_min_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB8_1 +; CHECK-ARM8-NEXT: .LBB8_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r1, [r0] +; CHECK-ARM8-NEXT: sxtb r2, r1 +; CHECK-ARM8-NEXT: mov r0, r2 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r2, #2 +; CHECK-ARM8-NEXT: movlt r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB8_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_min_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB8_1 +; CHECK-ARM6-NEXT: .LBB8_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI8_0 +; CHECK-ARM6-NEXT: ldrexb r1, [r0] +; CHECK-ARM6-NEXT: sxtb r2, r1 +; CHECK-ARM6-NEXT: mov r0, r2 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r2, #2 +; CHECK-ARM6-NEXT: movlt r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI8_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB8_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI8_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_min_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB8_1 +; CHECK-THUMB2-NEXT: .LBB8_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: sxtb r3, r0 +; CHECK-THUMB2-NEXT: mov r1, r3 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r3, #2 +; CHECK-THUMB2-NEXT: it lt +; CHECK-THUMB2-NEXT: movlt r1, r0 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB8_1 +; CHECK-THUMB2-NEXT: b .LBB8_2 +; CHECK-THUMB2-NEXT: .LBB8_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_min_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI8_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_min_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI8_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw min i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_umax_i8() { +; CHECK-ARM8-LABEL: test_umax_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB9_1 +; CHECK-ARM8-NEXT: .LBB9_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movhi r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB9_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umax_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB9_1 +; CHECK-ARM6-NEXT: .LBB9_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI9_0 +; CHECK-ARM6-NEXT: ldrexb r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: movhi r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI9_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB9_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI9_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_umax_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB9_1 +; CHECK-THUMB2-NEXT: .LBB9_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #1 +; CHECK-THUMB2-NEXT: it hi +; CHECK-THUMB2-NEXT: movhi r1, r0 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB9_1 +; CHECK-THUMB2-NEXT: b .LBB9_2 +; CHECK-THUMB2-NEXT: .LBB9_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umax_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI9_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umax_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI9_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw umax i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} +define i8 @test_umin_i8() { +; CHECK-ARM8-LABEL: test_umin_i8: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB10_1 +; CHECK-ARM8-NEXT: .LBB10_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: ldrexb r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r1, #2 +; CHECK-ARM8-NEXT: movlo r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r1, r0, #255 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-ARM8-NEXT: strexb r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB10_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umin_i8: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB10_1 +; CHECK-ARM6-NEXT: .LBB10_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI10_0 +; CHECK-ARM6-NEXT: ldrexb r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r1, #2 +; CHECK-ARM6-NEXT: movlo r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r1, r0, #255 +; CHECK-ARM6-NEXT: ldr r2, .LCPI10_0 +; CHECK-ARM6-NEXT: strexb r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB10_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI10_0: +; CHECK-ARM6-NEXT: .long atomic_i8 +; +; CHECK-THUMB2-LABEL: test_umin_i8: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB10_1 +; CHECK-THUMB2-NEXT: .LBB10_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i8 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i8 +; CHECK-THUMB2-NEXT: ldrexb r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #2 +; CHECK-THUMB2-NEXT: it lo +; CHECK-THUMB2-NEXT: movlo r1, r0 +; CHECK-THUMB2-NEXT: strexb r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB10_1 +; CHECK-THUMB2-NEXT: b .LBB10_2 +; CHECK-THUMB2-NEXT: .LBB10_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umin_i8: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI10_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umin_1 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI10_0: +; CHECK-THUMB1-NEXT: .long atomic_i8 +entry: + %0 = atomicrmw umin i8* @atomic_i8, i8 1 monotonic + ret i8 %0 +} + + +define i16 @test_xchg_i16() { +; CHECK-ARM8-LABEL: test_xchg_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB11_1 +; CHECK-ARM8-NEXT: .LBB11_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: mov r1, #1 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB11_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xchg_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB11_1 +; CHECK-ARM6-NEXT: .LBB11_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI11_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI11_0 +; CHECK-ARM6-NEXT: mov r1, #1 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB11_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI11_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_xchg_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB11_1 +; CHECK-THUMB2-NEXT: .LBB11_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB11_1 +; CHECK-THUMB2-NEXT: b .LBB11_2 +; CHECK-THUMB2-NEXT: .LBB11_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xchg_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI11_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_lock_test_and_set_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI11_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw xchg i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_add_i16() { +; CHECK-ARM8-LABEL: test_add_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB12_1 +; CHECK-ARM8-NEXT: .LBB12_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: add r0, r0, r1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB12_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_add_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB12_1 +; CHECK-ARM6-NEXT: .LBB12_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI12_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: add r0, r0, #1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI12_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB12_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI12_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_add_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB12_1 +; CHECK-THUMB2-NEXT: .LBB12_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: adds r1, r0, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB12_1 +; CHECK-THUMB2-NEXT: b .LBB12_2 +; CHECK-THUMB2-NEXT: .LBB12_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_add_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI12_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_add_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI12_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw add i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_sub_i16() { +; CHECK-ARM8-LABEL: test_sub_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB13_1 +; CHECK-ARM8-NEXT: .LBB13_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: sub r0, r0, r1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB13_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_sub_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB13_1 +; CHECK-ARM6-NEXT: .LBB13_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI13_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: sub r0, r0, #1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI13_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB13_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI13_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_sub_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB13_1 +; CHECK-THUMB2-NEXT: .LBB13_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: subs r1, r0, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB13_1 +; CHECK-THUMB2-NEXT: b .LBB13_2 +; CHECK-THUMB2-NEXT: .LBB13_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_sub_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI13_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_sub_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI13_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw sub i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_and_i16() { +; CHECK-ARM8-LABEL: test_and_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB14_1 +; CHECK-ARM8-NEXT: .LBB14_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r0, r0, #1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB14_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_and_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB14_1 +; CHECK-ARM6-NEXT: .LBB14_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI14_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r0, r0, #1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI14_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB14_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI14_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_and_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB14_1 +; CHECK-THUMB2-NEXT: .LBB14_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: and r1, r0, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB14_1 +; CHECK-THUMB2-NEXT: b .LBB14_2 +; CHECK-THUMB2-NEXT: .LBB14_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_and_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI14_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_and_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI14_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw and i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_nand_i16() { +; CHECK-ARM8-LABEL: test_nand_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB15_1 +; CHECK-ARM8-NEXT: .LBB15_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mvn r0, r0 +; CHECK-ARM8-NEXT: mvn r1, #1 +; CHECK-ARM8-NEXT: orr r0, r0, r1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB15_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_nand_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB15_1 +; CHECK-ARM6-NEXT: .LBB15_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI15_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mvn r0, r0 +; CHECK-ARM6-NEXT: mvn r1, #1 +; CHECK-ARM6-NEXT: orr r0, r0, r1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI15_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB15_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI15_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_nand_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB15_1 +; CHECK-THUMB2-NEXT: .LBB15_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r1, [r2] +; CHECK-THUMB2-NEXT: mov r0, r1 +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movw r0, #65534 +; CHECK-THUMB2-NEXT: orn r1, r0, r1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB15_1 +; CHECK-THUMB2-NEXT: b .LBB15_2 +; CHECK-THUMB2-NEXT: .LBB15_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_nand_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI15_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_nand_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI15_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw nand i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_or_i16() { +; CHECK-ARM8-LABEL: test_or_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB16_1 +; CHECK-ARM8-NEXT: .LBB16_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, #1 +; CHECK-ARM8-NEXT: orr r0, r0, r1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB16_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_or_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB16_1 +; CHECK-ARM6-NEXT: .LBB16_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI16_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: orr r0, r0, #1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI16_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB16_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI16_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_or_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB16_1 +; CHECK-THUMB2-NEXT: .LBB16_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: orr r1, r0, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB16_1 +; CHECK-THUMB2-NEXT: b .LBB16_2 +; CHECK-THUMB2-NEXT: .LBB16_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_or_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI16_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_or_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI16_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw or i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_xor_i16() { +; CHECK-ARM8-LABEL: test_xor_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB17_1 +; CHECK-ARM8-NEXT: .LBB17_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: eor r0, r0, #1 +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB17_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xor_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB17_1 +; CHECK-ARM6-NEXT: .LBB17_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI17_0 +; CHECK-ARM6-NEXT: ldrexh r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: eor r0, r0, #1 +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI17_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB17_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI17_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_xor_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB17_1 +; CHECK-THUMB2-NEXT: .LBB17_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: eor r1, r0, #1 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB17_1 +; CHECK-THUMB2-NEXT: b .LBB17_2 +; CHECK-THUMB2-NEXT: .LBB17_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xor_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI17_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_xor_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI17_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw xor i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_max_i16() { +; CHECK-ARM8-LABEL: test_max_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB18_1 +; CHECK-ARM8-NEXT: .LBB18_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r1, [r0] +; CHECK-ARM8-NEXT: sxth r2, r1 +; CHECK-ARM8-NEXT: mov r0, r2 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r2, #1 +; CHECK-ARM8-NEXT: movgt r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB18_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_max_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB18_1 +; CHECK-ARM6-NEXT: .LBB18_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI18_0 +; CHECK-ARM6-NEXT: ldrexh r1, [r0] +; CHECK-ARM6-NEXT: sxth r2, r1 +; CHECK-ARM6-NEXT: mov r0, r2 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r2, #1 +; CHECK-ARM6-NEXT: movgt r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI18_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB18_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI18_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_max_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB18_1 +; CHECK-THUMB2-NEXT: .LBB18_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: sxth r3, r0 +; CHECK-THUMB2-NEXT: mov r1, r3 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r3, #1 +; CHECK-THUMB2-NEXT: it gt +; CHECK-THUMB2-NEXT: movgt r1, r0 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB18_1 +; CHECK-THUMB2-NEXT: b .LBB18_2 +; CHECK-THUMB2-NEXT: .LBB18_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_max_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI18_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_max_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI18_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw max i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_min_i16() { +; CHECK-ARM8-LABEL: test_min_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB19_1 +; CHECK-ARM8-NEXT: .LBB19_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r1, [r0] +; CHECK-ARM8-NEXT: sxth r2, r1 +; CHECK-ARM8-NEXT: mov r0, r2 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r2, #2 +; CHECK-ARM8-NEXT: movlt r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB19_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_min_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB19_1 +; CHECK-ARM6-NEXT: .LBB19_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI19_0 +; CHECK-ARM6-NEXT: ldrexh r1, [r0] +; CHECK-ARM6-NEXT: sxth r2, r1 +; CHECK-ARM6-NEXT: mov r0, r2 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r2, #2 +; CHECK-ARM6-NEXT: movlt r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI19_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB19_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI19_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_min_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB19_1 +; CHECK-THUMB2-NEXT: .LBB19_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: sxth r3, r0 +; CHECK-THUMB2-NEXT: mov r1, r3 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r3, #2 +; CHECK-THUMB2-NEXT: it lt +; CHECK-THUMB2-NEXT: movlt r1, r0 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB19_1 +; CHECK-THUMB2-NEXT: b .LBB19_2 +; CHECK-THUMB2-NEXT: .LBB19_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_min_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI19_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_min_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI19_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw min i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_umax_i16() { +; CHECK-ARM8-LABEL: test_umax_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB20_1 +; CHECK-ARM8-NEXT: .LBB20_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movhi r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB20_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umax_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB20_1 +; CHECK-ARM6-NEXT: .LBB20_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI20_0 +; CHECK-ARM6-NEXT: ldrexh r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: movhi r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI20_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB20_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI20_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_umax_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB20_1 +; CHECK-THUMB2-NEXT: .LBB20_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #1 +; CHECK-THUMB2-NEXT: it hi +; CHECK-THUMB2-NEXT: movhi r1, r0 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB20_1 +; CHECK-THUMB2-NEXT: b .LBB20_2 +; CHECK-THUMB2-NEXT: .LBB20_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umax_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI20_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umax_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI20_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw umax i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} +define i16 @test_umin_i16() { +; CHECK-ARM8-LABEL: test_umin_i16: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB21_1 +; CHECK-ARM8-NEXT: .LBB21_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: ldrexh r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r0, #1 +; CHECK-ARM8-NEXT: cmp r1, #2 +; CHECK-ARM8-NEXT: movlo r0, r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: uxth r1, r0 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-ARM8-NEXT: strexh r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB21_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umin_i16: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB21_1 +; CHECK-ARM6-NEXT: .LBB21_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI21_0 +; CHECK-ARM6-NEXT: ldrexh r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r0, #1 +; CHECK-ARM6-NEXT: cmp r1, #2 +; CHECK-ARM6-NEXT: movlo r0, r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: uxth r1, r0 +; CHECK-ARM6-NEXT: ldr r2, .LCPI21_0 +; CHECK-ARM6-NEXT: strexh r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB21_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI21_0: +; CHECK-ARM6-NEXT: .long atomic_i16 +; +; CHECK-THUMB2-LABEL: test_umin_i16: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB21_1 +; CHECK-THUMB2-NEXT: .LBB21_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i16 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i16 +; CHECK-THUMB2-NEXT: ldrexh r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #2 +; CHECK-THUMB2-NEXT: it lo +; CHECK-THUMB2-NEXT: movlo r1, r0 +; CHECK-THUMB2-NEXT: strexh r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB21_1 +; CHECK-THUMB2-NEXT: b .LBB21_2 +; CHECK-THUMB2-NEXT: .LBB21_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umin_i16: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI21_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umin_2 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI21_0: +; CHECK-THUMB1-NEXT: .long atomic_i16 +entry: + %0 = atomicrmw umin i16* @atomic_i16, i16 1 monotonic + ret i16 %0 +} + + +define i32 @test_xchg_i32() { +; CHECK-ARM8-LABEL: test_xchg_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB22_1 +; CHECK-ARM8-NEXT: .LBB22_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: mov r1, #1 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB22_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xchg_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB22_1 +; CHECK-ARM6-NEXT: .LBB22_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI22_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI22_0 +; CHECK-ARM6-NEXT: mov r1, #1 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB22_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI22_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_xchg_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB22_1 +; CHECK-THUMB2-NEXT: .LBB22_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB22_1 +; CHECK-THUMB2-NEXT: b .LBB22_2 +; CHECK-THUMB2-NEXT: .LBB22_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xchg_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI22_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_lock_test_and_set_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI22_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw xchg i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_add_i32() { +; CHECK-ARM8-LABEL: test_add_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB23_1 +; CHECK-ARM8-NEXT: .LBB23_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: add r1, r0, #1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB23_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_add_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB23_1 +; CHECK-ARM6-NEXT: .LBB23_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI23_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: add r1, r0, #1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI23_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB23_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI23_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_add_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB23_1 +; CHECK-THUMB2-NEXT: .LBB23_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: adds r1, r0, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB23_1 +; CHECK-THUMB2-NEXT: b .LBB23_2 +; CHECK-THUMB2-NEXT: .LBB23_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_add_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI23_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_add_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI23_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw add i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_sub_i32() { +; CHECK-ARM8-LABEL: test_sub_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB24_1 +; CHECK-ARM8-NEXT: .LBB24_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: sub r1, r0, #1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB24_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_sub_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB24_1 +; CHECK-ARM6-NEXT: .LBB24_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI24_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: sub r1, r0, #1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI24_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB24_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI24_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_sub_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB24_1 +; CHECK-THUMB2-NEXT: .LBB24_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: subs r1, r0, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB24_1 +; CHECK-THUMB2-NEXT: b .LBB24_2 +; CHECK-THUMB2-NEXT: .LBB24_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_sub_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI24_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_sub_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI24_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw sub i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_and_i32() { +; CHECK-ARM8-LABEL: test_and_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB25_1 +; CHECK-ARM8-NEXT: .LBB25_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r1, r0, #1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB25_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_and_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB25_1 +; CHECK-ARM6-NEXT: .LBB25_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI25_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r1, r0, #1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI25_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB25_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI25_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_and_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB25_1 +; CHECK-THUMB2-NEXT: .LBB25_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: and r1, r0, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB25_1 +; CHECK-THUMB2-NEXT: b .LBB25_2 +; CHECK-THUMB2-NEXT: .LBB25_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_and_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI25_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_and_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI25_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw and i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_nand_i32() { +; CHECK-ARM8-LABEL: test_nand_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB26_1 +; CHECK-ARM8-NEXT: .LBB26_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r0, r0, #1 +; CHECK-ARM8-NEXT: mvn r1, #0 +; CHECK-ARM8-NEXT: eor r1, r0, r1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB26_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_nand_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB26_1 +; CHECK-ARM6-NEXT: .LBB26_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI26_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r0, r0, #1 +; CHECK-ARM6-NEXT: ldr r1, .LCPI26_1 +; CHECK-ARM6-NEXT: eor r1, r0, r1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI26_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB26_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI26_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; CHECK-ARM6-NEXT: .LCPI26_1: +; CHECK-ARM6-NEXT: .long 4294967295 @ 0xffffffff +; +; CHECK-THUMB2-LABEL: test_nand_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB26_1 +; CHECK-THUMB2-NEXT: .LBB26_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r1, [r2] +; CHECK-THUMB2-NEXT: mov r0, r1 +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mvn r0, #1 +; CHECK-THUMB2-NEXT: orn r1, r0, r1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB26_1 +; CHECK-THUMB2-NEXT: b .LBB26_2 +; CHECK-THUMB2-NEXT: .LBB26_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_nand_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI26_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_nand_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI26_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw nand i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_or_i32() { +; CHECK-ARM8-LABEL: test_or_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB27_1 +; CHECK-ARM8-NEXT: .LBB27_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: orr r1, r0, #1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB27_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_or_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB27_1 +; CHECK-ARM6-NEXT: .LBB27_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI27_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: orr r1, r0, #1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI27_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB27_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI27_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_or_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB27_1 +; CHECK-THUMB2-NEXT: .LBB27_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: orr r1, r0, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB27_1 +; CHECK-THUMB2-NEXT: b .LBB27_2 +; CHECK-THUMB2-NEXT: .LBB27_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_or_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI27_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_or_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI27_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw or i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_xor_i32() { +; CHECK-ARM8-LABEL: test_xor_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #4 +; CHECK-ARM8-NEXT: b .LBB28_1 +; CHECK-ARM8-NEXT: .LBB28_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r0, [r0] +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: eor r1, r0, #1 +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB28_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #4 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xor_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #4 +; CHECK-ARM6-NEXT: b .LBB28_1 +; CHECK-ARM6-NEXT: .LBB28_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI28_0 +; CHECK-ARM6-NEXT: ldrex r0, [r0] +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: eor r1, r0, #1 +; CHECK-ARM6-NEXT: ldr r2, .LCPI28_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB28_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #4 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI28_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; +; CHECK-THUMB2-LABEL: test_xor_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB28_1 +; CHECK-THUMB2-NEXT: .LBB28_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: eor r1, r0, #1 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB28_1 +; CHECK-THUMB2-NEXT: b .LBB28_2 +; CHECK-THUMB2-NEXT: .LBB28_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xor_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI28_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_xor_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI28_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw xor i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_max_i32() { +; CHECK-ARM8-LABEL: test_max_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #12 +; CHECK-ARM8-NEXT: b .LBB29_1 +; CHECK-ARM8-NEXT: .LBB29_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movw r0, #0 +; CHECK-ARM8-NEXT: movgt r0, #1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: tst r0, #1 +; CHECK-ARM8-NEXT: moveq r1, #1 +; CHECK-ARM8-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB29_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #12 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_max_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #12 +; CHECK-ARM6-NEXT: b .LBB29_1 +; CHECK-ARM6-NEXT: .LBB29_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI29_0 +; CHECK-ARM6-NEXT: ldrex r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI29_1 +; CHECK-ARM6-NEXT: movgt r0, #1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: tst r0, #1 +; CHECK-ARM6-NEXT: moveq r1, #1 +; CHECK-ARM6-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI29_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB29_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #12 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI29_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; CHECK-ARM6-NEXT: .LCPI29_1: +; CHECK-ARM6-NEXT: .long 0 @ 0x0 +; +; CHECK-THUMB2-LABEL: test_max_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB29_1 +; CHECK-THUMB2-NEXT: .LBB29_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #1 +; CHECK-THUMB2-NEXT: it gt +; CHECK-THUMB2-NEXT: movgt r1, r0 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB29_1 +; CHECK-THUMB2-NEXT: b .LBB29_2 +; CHECK-THUMB2-NEXT: .LBB29_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_max_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI29_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_max_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI29_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw max i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_min_i32() { +; CHECK-ARM8-LABEL: test_min_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #12 +; CHECK-ARM8-NEXT: b .LBB30_1 +; CHECK-ARM8-NEXT: .LBB30_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movw r0, #0 +; CHECK-ARM8-NEXT: movle r0, #1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: tst r0, #1 +; CHECK-ARM8-NEXT: moveq r1, #1 +; CHECK-ARM8-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB30_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #12 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_min_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #12 +; CHECK-ARM6-NEXT: b .LBB30_1 +; CHECK-ARM6-NEXT: .LBB30_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI30_0 +; CHECK-ARM6-NEXT: ldrex r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI30_1 +; CHECK-ARM6-NEXT: movle r0, #1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: tst r0, #1 +; CHECK-ARM6-NEXT: moveq r1, #1 +; CHECK-ARM6-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI30_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB30_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #12 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI30_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; CHECK-ARM6-NEXT: .LCPI30_1: +; CHECK-ARM6-NEXT: .long 0 @ 0x0 +; +; CHECK-THUMB2-LABEL: test_min_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB30_1 +; CHECK-THUMB2-NEXT: .LBB30_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #2 +; CHECK-THUMB2-NEXT: it lt +; CHECK-THUMB2-NEXT: movlt r1, r0 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB30_1 +; CHECK-THUMB2-NEXT: b .LBB30_2 +; CHECK-THUMB2-NEXT: .LBB30_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_min_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI30_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_min_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI30_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw min i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_umax_i32() { +; CHECK-ARM8-LABEL: test_umax_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #12 +; CHECK-ARM8-NEXT: b .LBB31_1 +; CHECK-ARM8-NEXT: .LBB31_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movw r0, #0 +; CHECK-ARM8-NEXT: movhi r0, #1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: tst r0, #1 +; CHECK-ARM8-NEXT: moveq r1, #1 +; CHECK-ARM8-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB31_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #12 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umax_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #12 +; CHECK-ARM6-NEXT: b .LBB31_1 +; CHECK-ARM6-NEXT: .LBB31_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI31_0 +; CHECK-ARM6-NEXT: ldrex r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI31_1 +; CHECK-ARM6-NEXT: movhi r0, #1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: tst r0, #1 +; CHECK-ARM6-NEXT: moveq r1, #1 +; CHECK-ARM6-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI31_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB31_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #12 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI31_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; CHECK-ARM6-NEXT: .LCPI31_1: +; CHECK-ARM6-NEXT: .long 0 @ 0x0 +; +; CHECK-THUMB2-LABEL: test_umax_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB31_1 +; CHECK-THUMB2-NEXT: .LBB31_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #1 +; CHECK-THUMB2-NEXT: it hi +; CHECK-THUMB2-NEXT: movhi r1, r0 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB31_1 +; CHECK-THUMB2-NEXT: b .LBB31_2 +; CHECK-THUMB2-NEXT: .LBB31_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umax_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI31_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umax_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI31_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw umax i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} +define i32 @test_umin_i32() { +; CHECK-ARM8-LABEL: test_umin_i32: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #12 +; CHECK-ARM8-NEXT: b .LBB32_1 +; CHECK-ARM8-NEXT: .LBB32_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: ldrex r1, [r0] +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: cmp r1, #1 +; CHECK-ARM8-NEXT: movw r0, #0 +; CHECK-ARM8-NEXT: movls r0, #1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: tst r0, #1 +; CHECK-ARM8-NEXT: moveq r1, #1 +; CHECK-ARM8-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-ARM8-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-ARM8-NEXT: strex r0, r1, [r2] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB32_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #12 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_umin_i32: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #12 +; CHECK-ARM6-NEXT: b .LBB32_1 +; CHECK-ARM6-NEXT: .LBB32_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI32_0 +; CHECK-ARM6-NEXT: ldrex r1, [r0] +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: cmp r1, #1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI32_1 +; CHECK-ARM6-NEXT: movls r0, #1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: tst r0, #1 +; CHECK-ARM6-NEXT: moveq r1, #1 +; CHECK-ARM6-NEXT: str r1, [sp, #8] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r2, .LCPI32_0 +; CHECK-ARM6-NEXT: strex r0, r1, [r2] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB32_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #12 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI32_0: +; CHECK-ARM6-NEXT: .long atomic_i32 +; CHECK-ARM6-NEXT: .LCPI32_1: +; CHECK-ARM6-NEXT: .long 0 @ 0x0 +; +; CHECK-THUMB2-LABEL: test_umin_i32: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #4 +; CHECK-THUMB2-NEXT: b .LBB32_1 +; CHECK-THUMB2-NEXT: .LBB32_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r2, :lower16:atomic_i32 +; CHECK-THUMB2-NEXT: movt r2, :upper16:atomic_i32 +; CHECK-THUMB2-NEXT: ldrex r0, [r2] +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: cmp r0, #2 +; CHECK-THUMB2-NEXT: it lo +; CHECK-THUMB2-NEXT: movlo r1, r0 +; CHECK-THUMB2-NEXT: strex r0, r1, [r2] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB32_1 +; CHECK-THUMB2-NEXT: b .LBB32_2 +; CHECK-THUMB2-NEXT: .LBB32_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #4 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_umin_i32: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI32_0 +; CHECK-THUMB1-NEXT: movs r1, #1 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_umin_4 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI32_0: +; CHECK-THUMB1-NEXT: .long atomic_i32 +entry: + %0 = atomicrmw umin i32* @atomic_i32, i32 1 monotonic + ret i32 %0 +} + + + +define i64 @test_xchg_i64() { +; CHECK-ARM8-LABEL: test_xchg_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB33_1 +; CHECK-ARM8-NEXT: .LBB33_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM8-NEXT: mov r2, r1 +; CHECK-ARM8-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: mov r0, #0 +; CHECK-ARM8-NEXT: mov r2, #1 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB33_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xchg_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB33_1 +; CHECK-ARM6-NEXT: .LBB33_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI33_0 +; CHECK-ARM6-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM6-NEXT: mov r2, r1 +; CHECK-ARM6-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: ldr r1, .LCPI33_0 +; CHECK-ARM6-NEXT: mov r0, #0 +; CHECK-ARM6-NEXT: mov r2, #1 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB33_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI33_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_xchg_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB33_1 +; CHECK-THUMB2-NEXT: .LBB33_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r0, r1, [r3] +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: movs r2, #0 +; CHECK-THUMB2-NEXT: movs r1, #1 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB33_1 +; CHECK-THUMB2-NEXT: b .LBB33_2 +; CHECK-THUMB2-NEXT: .LBB33_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xchg_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI33_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_lock_test_and_set_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI33_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw xchg i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_add_i64() { +; CHECK-ARM8-LABEL: test_add_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB34_1 +; CHECK-ARM8-NEXT: .LBB34_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM8-NEXT: mov r0, r3 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r1, r2 +; CHECK-ARM8-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: adds r2, r1, #1 +; CHECK-ARM8-NEXT: adc r0, r0, #0 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB34_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_add_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB34_1 +; CHECK-ARM6-NEXT: .LBB34_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI34_0 +; CHECK-ARM6-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM6-NEXT: mov r0, r3 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r1, r2 +; CHECK-ARM6-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: adds r2, r1, #1 +; CHECK-ARM6-NEXT: adc r0, r0, #0 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI34_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB34_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI34_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_add_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB34_1 +; CHECK-THUMB2-NEXT: .LBB34_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r1, r0, [r3] +; CHECK-THUMB2-NEXT: mov r2, r0 +; CHECK-THUMB2-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r2, r1 +; CHECK-THUMB2-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: adds r1, #1 +; CHECK-THUMB2-NEXT: adc r2, r0, #0 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB34_1 +; CHECK-THUMB2-NEXT: b .LBB34_2 +; CHECK-THUMB2-NEXT: .LBB34_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_add_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI34_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_add_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI34_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw add i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_sub_i64() { +; CHECK-ARM8-LABEL: test_sub_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB35_1 +; CHECK-ARM8-NEXT: .LBB35_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM8-NEXT: mov r0, r3 +; CHECK-ARM8-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r1, r2 +; CHECK-ARM8-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: subs r2, r1, #1 +; CHECK-ARM8-NEXT: sbc r0, r0, #0 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB35_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_sub_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB35_1 +; CHECK-ARM6-NEXT: .LBB35_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI35_0 +; CHECK-ARM6-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM6-NEXT: mov r0, r3 +; CHECK-ARM6-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r1, r2 +; CHECK-ARM6-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: subs r2, r1, #1 +; CHECK-ARM6-NEXT: sbc r0, r0, #0 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI35_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB35_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI35_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_sub_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB35_1 +; CHECK-THUMB2-NEXT: .LBB35_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r1, r0, [r3] +; CHECK-THUMB2-NEXT: mov r2, r0 +; CHECK-THUMB2-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r2, r1 +; CHECK-THUMB2-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: subs r1, #1 +; CHECK-THUMB2-NEXT: sbc r2, r0, #0 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB35_1 +; CHECK-THUMB2-NEXT: b .LBB35_2 +; CHECK-THUMB2-NEXT: .LBB35_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_sub_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI35_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_sub_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI35_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw sub i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_and_i64() { +; CHECK-ARM8-LABEL: test_and_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB36_1 +; CHECK-ARM8-NEXT: .LBB36_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM8-NEXT: mov r2, r1 +; CHECK-ARM8-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: and r2, r0, #1 +; CHECK-ARM8-NEXT: mov r0, #0 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB36_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_and_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB36_1 +; CHECK-ARM6-NEXT: .LBB36_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI36_0 +; CHECK-ARM6-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM6-NEXT: mov r2, r1 +; CHECK-ARM6-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: and r2, r0, #1 +; CHECK-ARM6-NEXT: mov r0, #0 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI36_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB36_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI36_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_and_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB36_1 +; CHECK-THUMB2-NEXT: .LBB36_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r0, r1, [r3] +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: and r1, r0, #1 +; CHECK-THUMB2-NEXT: movs r2, #0 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB36_1 +; CHECK-THUMB2-NEXT: b .LBB36_2 +; CHECK-THUMB2-NEXT: .LBB36_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_and_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI36_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_and_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI36_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw and i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_nand_i64() { +; CHECK-ARM8-LABEL: test_nand_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB37_1 +; CHECK-ARM8-NEXT: .LBB37_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM8-NEXT: mov r2, r1 +; CHECK-ARM8-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM8-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: mvn r0, r0 +; CHECK-ARM8-NEXT: mvn r1, #1 +; CHECK-ARM8-NEXT: orr r2, r0, r1 +; CHECK-ARM8-NEXT: mvn r0, #0 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB37_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_nand_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB37_1 +; CHECK-ARM6-NEXT: .LBB37_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI37_0 +; CHECK-ARM6-NEXT: ldrexd r0, r1, [r0] +; CHECK-ARM6-NEXT: mov r2, r1 +; CHECK-ARM6-NEXT: str r2, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: @ kill: def $r0 killed $r0 killed $r0_r1 +; CHECK-ARM6-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: mvn r0, r0 +; CHECK-ARM6-NEXT: mvn r1, #1 +; CHECK-ARM6-NEXT: orr r2, r0, r1 +; CHECK-ARM6-NEXT: mvn r0, #0 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI37_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB37_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI37_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_nand_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB37_1 +; CHECK-THUMB2-NEXT: .LBB37_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r1, r0, [r3] +; CHECK-THUMB2-NEXT: str r0, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r0, r1 +; CHECK-THUMB2-NEXT: str r0, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mvn r0, #1 +; CHECK-THUMB2-NEXT: orn r1, r0, r1 +; CHECK-THUMB2-NEXT: mov.w r2, #-1 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB37_1 +; CHECK-THUMB2-NEXT: b .LBB37_2 +; CHECK-THUMB2-NEXT: .LBB37_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_nand_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI37_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_nand_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI37_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw nand i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_or_i64() { +; CHECK-ARM8-LABEL: test_or_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB38_1 +; CHECK-ARM8-NEXT: .LBB38_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM8-NEXT: mov r0, r3 +; CHECK-ARM8-NEXT: mov r1, r2 +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r2, r0 +; CHECK-ARM8-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: orr r2, r1, #1 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB38_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_or_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB38_1 +; CHECK-ARM6-NEXT: .LBB38_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI38_0 +; CHECK-ARM6-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM6-NEXT: mov r0, r3 +; CHECK-ARM6-NEXT: mov r1, r2 +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r2, r0 +; CHECK-ARM6-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: orr r2, r1, #1 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI38_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB38_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI38_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_or_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB38_1 +; CHECK-THUMB2-NEXT: .LBB38_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r0, r2, [r3] +; CHECK-THUMB2-NEXT: mov r1, r2 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: orr r1, r0, #1 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB38_1 +; CHECK-THUMB2-NEXT: b .LBB38_2 +; CHECK-THUMB2-NEXT: .LBB38_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_or_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI38_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_or_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI38_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw or i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +} +define i64 @test_xor_i64() { +; CHECK-ARM8-LABEL: test_xor_i64: +; CHECK-ARM8: @ %bb.0: @ %entry +; CHECK-ARM8-NEXT: sub sp, sp, #8 +; CHECK-ARM8-NEXT: b .LBB39_1 +; CHECK-ARM8-NEXT: .LBB39_1: @ %atomicrmw.start +; CHECK-ARM8-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM8-NEXT: movw r0, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r0, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM8-NEXT: mov r0, r3 +; CHECK-ARM8-NEXT: mov r1, r2 +; CHECK-ARM8-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM8-NEXT: mov r2, r0 +; CHECK-ARM8-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-ARM8-NEXT: eor r2, r1, #1 +; CHECK-ARM8-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM8-NEXT: mov r3, r0 +; CHECK-ARM8-NEXT: movw r1, :lower16:atomic_i64 +; CHECK-ARM8-NEXT: movt r1, :upper16:atomic_i64 +; CHECK-ARM8-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM8-NEXT: cmp r0, #0 +; CHECK-ARM8-NEXT: bne .LBB39_1 +; CHECK-ARM8-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM8-NEXT: ldr r1, [sp, #4] @ 4-byte Reload +; CHECK-ARM8-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM8-NEXT: add sp, sp, #8 +; CHECK-ARM8-NEXT: bx lr +; +; CHECK-ARM6-LABEL: test_xor_i64: +; CHECK-ARM6: @ %bb.0: @ %entry +; CHECK-ARM6-NEXT: sub sp, sp, #8 +; CHECK-ARM6-NEXT: b .LBB39_1 +; CHECK-ARM6-NEXT: .LBB39_1: @ %atomicrmw.start +; CHECK-ARM6-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-ARM6-NEXT: ldr r0, .LCPI39_0 +; CHECK-ARM6-NEXT: ldrexd r2, r3, [r0] +; CHECK-ARM6-NEXT: mov r0, r3 +; CHECK-ARM6-NEXT: mov r1, r2 +; CHECK-ARM6-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-ARM6-NEXT: mov r2, r0 +; CHECK-ARM6-NEXT: str r2, [sp, #4] @ 4-byte Spill +; CHECK-ARM6-NEXT: eor r2, r1, #1 +; CHECK-ARM6-NEXT: @ kill: def $r2 killed $r2 def $r2_r3 +; CHECK-ARM6-NEXT: mov r3, r0 +; CHECK-ARM6-NEXT: ldr r1, .LCPI39_0 +; CHECK-ARM6-NEXT: strexd r0, r2, r3, [r1] +; CHECK-ARM6-NEXT: cmp r0, #0 +; CHECK-ARM6-NEXT: bne .LBB39_1 +; CHECK-ARM6-NEXT: @ %bb.2: @ %atomicrmw.end +; CHECK-ARM6-NEXT: ldr r1, [sp, #4] @ 4-byte Reload +; CHECK-ARM6-NEXT: ldr r0, [sp] @ 4-byte Reload +; CHECK-ARM6-NEXT: add sp, sp, #8 +; CHECK-ARM6-NEXT: bx lr +; CHECK-ARM6-NEXT: .p2align 2 +; CHECK-ARM6-NEXT: @ %bb.3: +; CHECK-ARM6-NEXT: .LCPI39_0: +; CHECK-ARM6-NEXT: .long atomic_i64 +; +; CHECK-THUMB2-LABEL: test_xor_i64: +; CHECK-THUMB2: @ %bb.0: @ %entry +; CHECK-THUMB2-NEXT: sub sp, #8 +; CHECK-THUMB2-NEXT: b .LBB39_1 +; CHECK-THUMB2-NEXT: .LBB39_1: @ %atomicrmw.start +; CHECK-THUMB2-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-THUMB2-NEXT: movw r3, :lower16:atomic_i64 +; CHECK-THUMB2-NEXT: movt r3, :upper16:atomic_i64 +; CHECK-THUMB2-NEXT: ldrexd r0, r2, [r3] +; CHECK-THUMB2-NEXT: mov r1, r2 +; CHECK-THUMB2-NEXT: str r1, [sp] @ 4-byte Spill +; CHECK-THUMB2-NEXT: mov r1, r0 +; CHECK-THUMB2-NEXT: str r1, [sp, #4] @ 4-byte Spill +; CHECK-THUMB2-NEXT: eor r1, r0, #1 +; CHECK-THUMB2-NEXT: strexd r0, r1, r2, [r3] +; CHECK-THUMB2-NEXT: cmp r0, #0 +; CHECK-THUMB2-NEXT: bne .LBB39_1 +; CHECK-THUMB2-NEXT: b .LBB39_2 +; CHECK-THUMB2-NEXT: .LBB39_2: @ %atomicrmw.end +; CHECK-THUMB2-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-THUMB2-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-THUMB2-NEXT: add sp, #8 +; CHECK-THUMB2-NEXT: bx lr +; +; CHECK-THUMB1-LABEL: test_xor_i64: +; CHECK-THUMB1: @ %bb.0: @ %entry +; CHECK-THUMB1-NEXT: push {r7, lr} +; CHECK-THUMB1-NEXT: ldr r0, .LCPI39_0 +; CHECK-THUMB1-NEXT: movs r2, #1 +; CHECK-THUMB1-NEXT: movs r3, #0 +; CHECK-THUMB1-NEXT: bl __sync_fetch_and_xor_8 +; CHECK-THUMB1-NEXT: pop {r7, pc} +; CHECK-THUMB1-NEXT: .p2align 2 +; CHECK-THUMB1-NEXT: @ %bb.1: +; CHECK-THUMB1-NEXT: .LCPI39_0: +; CHECK-THUMB1-NEXT: .long atomic_i64 +entry: + %0 = atomicrmw xor i64* @atomic_i64, i64 1 monotonic + ret i64 %0 +}