llvm-project/llvm/test/CodeGen/RISCV/atomic-signext.ll
Alex Bradbury 0ee10e9466
[RISCV] Add additional fence for amocas when required by recent ABI change (#101023)
A recent atomics ABI change / fix requires that for the "A6C" and A6S"
atomics ABIs (i.e. both of those supported by LLVM currently), an
additional fence is inserted for an atomic_compare_exchange with seq_cst
failure ordering.
<https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/445>

This isn't trivial to support through the hooks used by AtomicExpandPass
because that pass assumes that when fences are inserted, the original
atomics ordering information can be removed from the instruction. Rather
than try to change and complicate that API, this patch implements the
needed fence insertion through a small special purpose pass.
2024-09-19 13:39:56 +01:00

5638 lines
188 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-NOZACAS %s
; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-zacas -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32IA,RV32IA-ZACAS %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I %s
; RUN: llc -mtriple=riscv64 -mattr=+a -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-NOZACAS %s
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zacas -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZACAS %s
define signext i8 @atomic_load_i8_unordered(ptr %a) nounwind {
; RV32I-LABEL: atomic_load_i8_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: call __atomic_load_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomic_load_i8_unordered:
; RV32IA: # %bb.0:
; RV32IA-NEXT: lb a0, 0(a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomic_load_i8_unordered:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 0
; RV64I-NEXT: call __atomic_load_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomic_load_i8_unordered:
; RV64IA: # %bb.0:
; RV64IA-NEXT: lb a0, 0(a0)
; RV64IA-NEXT: ret
%1 = load atomic i8, ptr %a unordered, align 1
ret i8 %1
}
define signext i16 @atomic_load_i16_unordered(ptr %a) nounwind {
; RV32I-LABEL: atomic_load_i16_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: call __atomic_load_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomic_load_i16_unordered:
; RV32IA: # %bb.0:
; RV32IA-NEXT: lh a0, 0(a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomic_load_i16_unordered:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 0
; RV64I-NEXT: call __atomic_load_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomic_load_i16_unordered:
; RV64IA: # %bb.0:
; RV64IA-NEXT: lh a0, 0(a0)
; RV64IA-NEXT: ret
%1 = load atomic i16, ptr %a unordered, align 2
ret i16 %1
}
define signext i32 @atomic_load_i32_unordered(ptr %a) nounwind {
; RV32I-LABEL: atomic_load_i32_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: call __atomic_load_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomic_load_i32_unordered:
; RV32IA: # %bb.0:
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomic_load_i32_unordered:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 0
; RV64I-NEXT: call __atomic_load_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomic_load_i32_unordered:
; RV64IA: # %bb.0:
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: ret
%1 = load atomic i32, ptr %a unordered, align 4
ret i32 %1
}
define signext i8 @atomicrmw_xchg_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_xchg_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_exchange_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xchg_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: mv a5, a1
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB3_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xchg_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_exchange_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xchg_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: mv a5, a1
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB3_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw xchg ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_add_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_add_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_add_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_add_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: add a5, a4, a1
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB4_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_add_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_add_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_add_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: add a5, a4, a1
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB4_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw add ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_sub_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_sub_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_sub_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_sub_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: sub a5, a4, a1
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB5_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_sub_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_sub_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_sub_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: sub a5, a4, a1
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB5_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw sub ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_and_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_and_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_and_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_and_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: not a3, a3
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: or a1, a1, a3
; RV32IA-NEXT: amoand.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_and_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_and_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_and_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: not a3, a3
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: or a1, a1, a3
; RV64IA-NEXT: amoand.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw and ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_nand_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_nand_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_nand_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_nand_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: and a5, a4, a1
; RV32IA-NEXT: not a5, a5
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB7_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_nand_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_nand_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_nand_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: and a5, a4, a1
; RV64IA-NEXT: not a5, a5
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB7_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw nand ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_or_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_or_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_or_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_or_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: amoor.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_or_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_or_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_or_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: amoor.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw or ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_xor_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_xor_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_xor_1
; RV32I-NEXT: slli a0, a0, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xor_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: amoxor.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xor_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_xor_1
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xor_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: amoxor.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw xor ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_max_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_max_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lbu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: slli a0, a1, 24
; RV32I-NEXT: srai s2, a0, 24
; RV32I-NEXT: j .LBB10_2
; RV32I-NEXT: .LBB10_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB10_2 Depth=1
; RV32I-NEXT: sb a3, 15(sp)
; RV32I-NEXT: addi a1, sp, 15
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lbu a3, 15(sp)
; RV32I-NEXT: bnez a0, .LBB10_4
; RV32I-NEXT: .LBB10_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: blt s2, a0, .LBB10_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB10_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB10_1
; RV32I-NEXT: .LBB10_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_max_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a3, a0, 24
; RV32IA-NEXT: li a4, 255
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: slli a1, a1, 24
; RV32IA-NEXT: srai a1, a1, 24
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: xori a3, a3, 24
; RV32IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a5, (a2)
; RV32IA-NEXT: and a7, a5, a4
; RV32IA-NEXT: mv a6, a5
; RV32IA-NEXT: sll a7, a7, a3
; RV32IA-NEXT: sra a7, a7, a3
; RV32IA-NEXT: bge a7, a1, .LBB10_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB10_1 Depth=1
; RV32IA-NEXT: xor a6, a5, a1
; RV32IA-NEXT: and a6, a6, a4
; RV32IA-NEXT: xor a6, a5, a6
; RV32IA-NEXT: .LBB10_3: # in Loop: Header=BB10_1 Depth=1
; RV32IA-NEXT: sc.w a6, a6, (a2)
; RV32IA-NEXT: bnez a6, .LBB10_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a5, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_max_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lbu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: slli a0, a1, 56
; RV64I-NEXT: srai s2, a0, 56
; RV64I-NEXT: j .LBB10_2
; RV64I-NEXT: .LBB10_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB10_2 Depth=1
; RV64I-NEXT: sb a3, 15(sp)
; RV64I-NEXT: addi a1, sp, 15
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: lbu a3, 15(sp)
; RV64I-NEXT: bnez a0, .LBB10_4
; RV64I-NEXT: .LBB10_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: blt s2, a0, .LBB10_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB10_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB10_1
; RV64I-NEXT: .LBB10_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_max_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a3, a0, 24
; RV64IA-NEXT: li a4, 255
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: slli a1, a1, 56
; RV64IA-NEXT: srai a1, a1, 56
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: xori a3, a3, 56
; RV64IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a5, (a2)
; RV64IA-NEXT: and a7, a5, a4
; RV64IA-NEXT: mv a6, a5
; RV64IA-NEXT: sll a7, a7, a3
; RV64IA-NEXT: sra a7, a7, a3
; RV64IA-NEXT: bge a7, a1, .LBB10_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB10_1 Depth=1
; RV64IA-NEXT: xor a6, a5, a1
; RV64IA-NEXT: and a6, a6, a4
; RV64IA-NEXT: xor a6, a5, a6
; RV64IA-NEXT: .LBB10_3: # in Loop: Header=BB10_1 Depth=1
; RV64IA-NEXT: sc.w a6, a6, (a2)
; RV64IA-NEXT: bnez a6, .LBB10_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a5, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw max ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_min_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_min_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lbu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: slli a0, a1, 24
; RV32I-NEXT: srai s2, a0, 24
; RV32I-NEXT: j .LBB11_2
; RV32I-NEXT: .LBB11_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB11_2 Depth=1
; RV32I-NEXT: sb a3, 15(sp)
; RV32I-NEXT: addi a1, sp, 15
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lbu a3, 15(sp)
; RV32I-NEXT: bnez a0, .LBB11_4
; RV32I-NEXT: .LBB11_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bge s2, a0, .LBB11_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB11_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB11_1
; RV32I-NEXT: .LBB11_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_min_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a3, a0, 24
; RV32IA-NEXT: li a4, 255
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: slli a1, a1, 24
; RV32IA-NEXT: srai a1, a1, 24
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: xori a3, a3, 24
; RV32IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a5, (a2)
; RV32IA-NEXT: and a7, a5, a4
; RV32IA-NEXT: mv a6, a5
; RV32IA-NEXT: sll a7, a7, a3
; RV32IA-NEXT: sra a7, a7, a3
; RV32IA-NEXT: bge a1, a7, .LBB11_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB11_1 Depth=1
; RV32IA-NEXT: xor a6, a5, a1
; RV32IA-NEXT: and a6, a6, a4
; RV32IA-NEXT: xor a6, a5, a6
; RV32IA-NEXT: .LBB11_3: # in Loop: Header=BB11_1 Depth=1
; RV32IA-NEXT: sc.w a6, a6, (a2)
; RV32IA-NEXT: bnez a6, .LBB11_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a5, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_min_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lbu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: slli a0, a1, 56
; RV64I-NEXT: srai s2, a0, 56
; RV64I-NEXT: j .LBB11_2
; RV64I-NEXT: .LBB11_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB11_2 Depth=1
; RV64I-NEXT: sb a3, 15(sp)
; RV64I-NEXT: addi a1, sp, 15
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: lbu a3, 15(sp)
; RV64I-NEXT: bnez a0, .LBB11_4
; RV64I-NEXT: .LBB11_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bge s2, a0, .LBB11_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB11_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB11_1
; RV64I-NEXT: .LBB11_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_min_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a3, a0, 24
; RV64IA-NEXT: li a4, 255
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: slli a1, a1, 56
; RV64IA-NEXT: srai a1, a1, 56
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: xori a3, a3, 56
; RV64IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a5, (a2)
; RV64IA-NEXT: and a7, a5, a4
; RV64IA-NEXT: mv a6, a5
; RV64IA-NEXT: sll a7, a7, a3
; RV64IA-NEXT: sra a7, a7, a3
; RV64IA-NEXT: bge a1, a7, .LBB11_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB11_1 Depth=1
; RV64IA-NEXT: xor a6, a5, a1
; RV64IA-NEXT: and a6, a6, a4
; RV64IA-NEXT: xor a6, a5, a6
; RV64IA-NEXT: .LBB11_3: # in Loop: Header=BB11_1 Depth=1
; RV64IA-NEXT: sc.w a6, a6, (a2)
; RV64IA-NEXT: bnez a6, .LBB11_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a5, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw min ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_umax_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_umax_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lbu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: andi s2, a1, 255
; RV32I-NEXT: j .LBB12_2
; RV32I-NEXT: .LBB12_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB12_2 Depth=1
; RV32I-NEXT: sb a3, 15(sp)
; RV32I-NEXT: addi a1, sp, 15
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lbu a3, 15(sp)
; RV32I-NEXT: bnez a0, .LBB12_4
; RV32I-NEXT: .LBB12_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: andi a0, a3, 255
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bltu s2, a0, .LBB12_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB12_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB12_1
; RV32I-NEXT: .LBB12_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umax_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: and a6, a4, a3
; RV32IA-NEXT: mv a5, a4
; RV32IA-NEXT: bgeu a6, a1, .LBB12_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB12_1 Depth=1
; RV32IA-NEXT: xor a5, a4, a1
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: .LBB12_3: # in Loop: Header=BB12_1 Depth=1
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB12_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umax_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lbu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: andi s2, a1, 255
; RV64I-NEXT: j .LBB12_2
; RV64I-NEXT: .LBB12_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB12_2 Depth=1
; RV64I-NEXT: sb a3, 15(sp)
; RV64I-NEXT: addi a1, sp, 15
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: lbu a3, 15(sp)
; RV64I-NEXT: bnez a0, .LBB12_4
; RV64I-NEXT: .LBB12_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: andi a0, a3, 255
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bltu s2, a0, .LBB12_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB12_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB12_1
; RV64I-NEXT: .LBB12_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umax_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: and a6, a4, a3
; RV64IA-NEXT: mv a5, a4
; RV64IA-NEXT: bgeu a6, a1, .LBB12_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB12_1 Depth=1
; RV64IA-NEXT: xor a5, a4, a1
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: .LBB12_3: # in Loop: Header=BB12_1 Depth=1
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB12_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw umax ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i8 @atomicrmw_umin_i8_monotonic(ptr %a, i8 %b) nounwind {
; RV32I-LABEL: atomicrmw_umin_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lbu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: andi s2, a1, 255
; RV32I-NEXT: j .LBB13_2
; RV32I-NEXT: .LBB13_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB13_2 Depth=1
; RV32I-NEXT: sb a3, 15(sp)
; RV32I-NEXT: addi a1, sp, 15
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lbu a3, 15(sp)
; RV32I-NEXT: bnez a0, .LBB13_4
; RV32I-NEXT: .LBB13_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: andi a0, a3, 255
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bgeu s2, a0, .LBB13_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB13_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB13_1
; RV32I-NEXT: .LBB13_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 24
; RV32I-NEXT: srai a0, a0, 24
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umin_i8_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a3, 255
; RV32IA-NEXT: sll a3, a3, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a2)
; RV32IA-NEXT: and a6, a4, a3
; RV32IA-NEXT: mv a5, a4
; RV32IA-NEXT: bgeu a1, a6, .LBB13_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB13_1 Depth=1
; RV32IA-NEXT: xor a5, a4, a1
; RV32IA-NEXT: and a5, a5, a3
; RV32IA-NEXT: xor a5, a4, a5
; RV32IA-NEXT: .LBB13_3: # in Loop: Header=BB13_1 Depth=1
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB13_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umin_i8_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lbu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: andi s2, a1, 255
; RV64I-NEXT: j .LBB13_2
; RV64I-NEXT: .LBB13_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB13_2 Depth=1
; RV64I-NEXT: sb a3, 15(sp)
; RV64I-NEXT: addi a1, sp, 15
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: lbu a3, 15(sp)
; RV64I-NEXT: bnez a0, .LBB13_4
; RV64I-NEXT: .LBB13_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: andi a0, a3, 255
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bgeu s2, a0, .LBB13_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB13_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB13_1
; RV64I-NEXT: .LBB13_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umin_i8_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a3, 255
; RV64IA-NEXT: sllw a3, a3, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a2)
; RV64IA-NEXT: and a6, a4, a3
; RV64IA-NEXT: mv a5, a4
; RV64IA-NEXT: bgeu a1, a6, .LBB13_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB13_1 Depth=1
; RV64IA-NEXT: xor a5, a4, a1
; RV64IA-NEXT: and a5, a5, a3
; RV64IA-NEXT: xor a5, a4, a5
; RV64IA-NEXT: .LBB13_3: # in Loop: Header=BB13_1 Depth=1
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB13_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = atomicrmw umin ptr %a, i8 %b monotonic
ret i8 %1
}
define signext i16 @atomicrmw_xchg_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_xchg_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_exchange_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xchg_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: mv a5, a1
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB14_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xchg_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_exchange_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xchg_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: mv a5, a1
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB14_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw xchg ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_add_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_add_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_add_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_add_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: add a5, a3, a1
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB15_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_add_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_add_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_add_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: add a5, a3, a1
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB15_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw add ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_sub_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_sub_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_sub_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_sub_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: sub a5, a3, a1
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB16_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_sub_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_sub_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_sub_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: sub a5, a3, a1
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB16_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw sub ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_and_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_and_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_and_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_and_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: not a4, a4
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: or a1, a1, a4
; RV32IA-NEXT: amoand.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_and_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_and_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_and_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: not a4, a4
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: or a1, a1, a4
; RV64IA-NEXT: amoand.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw and ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_nand_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_nand_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_nand_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_nand_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: and a5, a3, a1
; RV32IA-NEXT: not a5, a5
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB18_1
; RV32IA-NEXT: # %bb.2:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_nand_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_nand_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_nand_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: and a5, a3, a1
; RV64IA-NEXT: not a5, a5
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB18_1
; RV64IA-NEXT: # %bb.2:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw nand ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_or_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_or_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_or_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_or_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: slli a1, a1, 16
; RV32IA-NEXT: srli a1, a1, 16
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: amoor.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_or_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_or_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_or_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: slli a1, a1, 48
; RV64IA-NEXT: srli a1, a1, 48
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: amoor.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw or ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_xor_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_xor_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_xor_2
; RV32I-NEXT: slli a0, a0, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xor_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: slli a1, a1, 16
; RV32IA-NEXT: srli a1, a1, 16
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: amoxor.w a1, a1, (a2)
; RV32IA-NEXT: srl a0, a1, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xor_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_xor_2
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xor_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: slli a1, a1, 48
; RV64IA-NEXT: srli a1, a1, 48
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: amoxor.w a1, a1, (a2)
; RV64IA-NEXT: srlw a0, a1, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw xor ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_max_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_max_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lhu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: slli a0, a1, 16
; RV32I-NEXT: srai s2, a0, 16
; RV32I-NEXT: j .LBB21_2
; RV32I-NEXT: .LBB21_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB21_2 Depth=1
; RV32I-NEXT: sh a3, 14(sp)
; RV32I-NEXT: addi a1, sp, 14
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lh a3, 14(sp)
; RV32I-NEXT: bnez a0, .LBB21_4
; RV32I-NEXT: .LBB21_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: slli a0, a3, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: blt s2, a0, .LBB21_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB21_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB21_1
; RV32I-NEXT: .LBB21_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_max_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a3, a0, 24
; RV32IA-NEXT: lui a4, 16
; RV32IA-NEXT: addi a4, a4, -1
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: slli a1, a1, 16
; RV32IA-NEXT: srai a1, a1, 16
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: li a5, 16
; RV32IA-NEXT: sub a5, a5, a3
; RV32IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: and a7, a3, a4
; RV32IA-NEXT: mv a6, a3
; RV32IA-NEXT: sll a7, a7, a5
; RV32IA-NEXT: sra a7, a7, a5
; RV32IA-NEXT: bge a7, a1, .LBB21_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1
; RV32IA-NEXT: xor a6, a3, a1
; RV32IA-NEXT: and a6, a6, a4
; RV32IA-NEXT: xor a6, a3, a6
; RV32IA-NEXT: .LBB21_3: # in Loop: Header=BB21_1 Depth=1
; RV32IA-NEXT: sc.w a6, a6, (a2)
; RV32IA-NEXT: bnez a6, .LBB21_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_max_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lhu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: slli a0, a1, 48
; RV64I-NEXT: srai s2, a0, 48
; RV64I-NEXT: j .LBB21_2
; RV64I-NEXT: .LBB21_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB21_2 Depth=1
; RV64I-NEXT: sh a3, 14(sp)
; RV64I-NEXT: addi a1, sp, 14
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: lh a3, 14(sp)
; RV64I-NEXT: bnez a0, .LBB21_4
; RV64I-NEXT: .LBB21_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: slli a0, a3, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: blt s2, a0, .LBB21_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB21_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB21_1
; RV64I-NEXT: .LBB21_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_max_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a3, a0, 24
; RV64IA-NEXT: lui a4, 16
; RV64IA-NEXT: addi a4, a4, -1
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: slli a1, a1, 48
; RV64IA-NEXT: srai a1, a1, 48
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: li a5, 48
; RV64IA-NEXT: sub a5, a5, a3
; RV64IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: and a7, a3, a4
; RV64IA-NEXT: mv a6, a3
; RV64IA-NEXT: sll a7, a7, a5
; RV64IA-NEXT: sra a7, a7, a5
; RV64IA-NEXT: bge a7, a1, .LBB21_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1
; RV64IA-NEXT: xor a6, a3, a1
; RV64IA-NEXT: and a6, a6, a4
; RV64IA-NEXT: xor a6, a3, a6
; RV64IA-NEXT: .LBB21_3: # in Loop: Header=BB21_1 Depth=1
; RV64IA-NEXT: sc.w a6, a6, (a2)
; RV64IA-NEXT: bnez a6, .LBB21_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw max ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_min_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_min_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lhu a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: slli a0, a1, 16
; RV32I-NEXT: srai s2, a0, 16
; RV32I-NEXT: j .LBB22_2
; RV32I-NEXT: .LBB22_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB22_2 Depth=1
; RV32I-NEXT: sh a3, 14(sp)
; RV32I-NEXT: addi a1, sp, 14
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lh a3, 14(sp)
; RV32I-NEXT: bnez a0, .LBB22_4
; RV32I-NEXT: .LBB22_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: slli a0, a3, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bge s2, a0, .LBB22_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB22_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB22_1
; RV32I-NEXT: .LBB22_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a3, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_min_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: andi a3, a0, 24
; RV32IA-NEXT: lui a4, 16
; RV32IA-NEXT: addi a4, a4, -1
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: slli a1, a1, 16
; RV32IA-NEXT: srai a1, a1, 16
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: li a5, 16
; RV32IA-NEXT: sub a5, a5, a3
; RV32IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: and a7, a3, a4
; RV32IA-NEXT: mv a6, a3
; RV32IA-NEXT: sll a7, a7, a5
; RV32IA-NEXT: sra a7, a7, a5
; RV32IA-NEXT: bge a1, a7, .LBB22_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1
; RV32IA-NEXT: xor a6, a3, a1
; RV32IA-NEXT: and a6, a6, a4
; RV32IA-NEXT: xor a6, a3, a6
; RV32IA-NEXT: .LBB22_3: # in Loop: Header=BB22_1 Depth=1
; RV32IA-NEXT: sc.w a6, a6, (a2)
; RV32IA-NEXT: bnez a6, .LBB22_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_min_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lhu a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: slli a0, a1, 48
; RV64I-NEXT: srai s2, a0, 48
; RV64I-NEXT: j .LBB22_2
; RV64I-NEXT: .LBB22_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB22_2 Depth=1
; RV64I-NEXT: sh a3, 14(sp)
; RV64I-NEXT: addi a1, sp, 14
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: lh a3, 14(sp)
; RV64I-NEXT: bnez a0, .LBB22_4
; RV64I-NEXT: .LBB22_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: slli a0, a3, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bge s2, a0, .LBB22_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB22_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB22_1
; RV64I-NEXT: .LBB22_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a3, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_min_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: andi a3, a0, 24
; RV64IA-NEXT: lui a4, 16
; RV64IA-NEXT: addi a4, a4, -1
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: slli a1, a1, 48
; RV64IA-NEXT: srai a1, a1, 48
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: li a5, 48
; RV64IA-NEXT: sub a5, a5, a3
; RV64IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: and a7, a3, a4
; RV64IA-NEXT: mv a6, a3
; RV64IA-NEXT: sll a7, a7, a5
; RV64IA-NEXT: sra a7, a7, a5
; RV64IA-NEXT: bge a1, a7, .LBB22_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1
; RV64IA-NEXT: xor a6, a3, a1
; RV64IA-NEXT: and a6, a6, a4
; RV64IA-NEXT: xor a6, a3, a6
; RV64IA-NEXT: .LBB22_3: # in Loop: Header=BB22_1 Depth=1
; RV64IA-NEXT: sc.w a6, a6, (a2)
; RV64IA-NEXT: bnez a6, .LBB22_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw min ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_umax_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_umax_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a1
; RV32I-NEXT: mv s1, a0
; RV32I-NEXT: lhu a1, 0(a0)
; RV32I-NEXT: lui s2, 16
; RV32I-NEXT: addi s2, s2, -1
; RV32I-NEXT: and s3, s0, s2
; RV32I-NEXT: j .LBB23_2
; RV32I-NEXT: .LBB23_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB23_2 Depth=1
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lh a1, 10(sp)
; RV32I-NEXT: bnez a0, .LBB23_4
; RV32I-NEXT: .LBB23_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: and a0, a1, s2
; RV32I-NEXT: mv a2, a1
; RV32I-NEXT: bltu s3, a0, .LBB23_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB23_2 Depth=1
; RV32I-NEXT: mv a2, s0
; RV32I-NEXT: j .LBB23_1
; RV32I-NEXT: .LBB23_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a1, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umax_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: and a6, a3, a4
; RV32IA-NEXT: mv a5, a3
; RV32IA-NEXT: bgeu a6, a1, .LBB23_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1
; RV32IA-NEXT: xor a5, a3, a1
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: .LBB23_3: # in Loop: Header=BB23_1 Depth=1
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB23_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umax_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: mv s1, a0
; RV64I-NEXT: lhu a1, 0(a0)
; RV64I-NEXT: lui s2, 16
; RV64I-NEXT: addiw s2, s2, -1
; RV64I-NEXT: and s3, s0, s2
; RV64I-NEXT: j .LBB23_2
; RV64I-NEXT: .LBB23_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB23_2 Depth=1
; RV64I-NEXT: sh a1, 6(sp)
; RV64I-NEXT: addi a1, sp, 6
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: lh a1, 6(sp)
; RV64I-NEXT: bnez a0, .LBB23_4
; RV64I-NEXT: .LBB23_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: and a0, a1, s2
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: bltu s3, a0, .LBB23_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB23_2 Depth=1
; RV64I-NEXT: mv a2, s0
; RV64I-NEXT: j .LBB23_1
; RV64I-NEXT: .LBB23_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a1, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umax_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: and a6, a3, a4
; RV64IA-NEXT: mv a5, a3
; RV64IA-NEXT: bgeu a6, a1, .LBB23_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1
; RV64IA-NEXT: xor a5, a3, a1
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: .LBB23_3: # in Loop: Header=BB23_1 Depth=1
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB23_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw umax ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i16 @atomicrmw_umin_i16_monotonic(ptr %a, i16 %b) nounwind {
; RV32I-LABEL: atomicrmw_umin_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a1
; RV32I-NEXT: mv s1, a0
; RV32I-NEXT: lhu a1, 0(a0)
; RV32I-NEXT: lui s2, 16
; RV32I-NEXT: addi s2, s2, -1
; RV32I-NEXT: and s3, s0, s2
; RV32I-NEXT: j .LBB24_2
; RV32I-NEXT: .LBB24_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB24_2 Depth=1
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: mv a0, s1
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lh a1, 10(sp)
; RV32I-NEXT: bnez a0, .LBB24_4
; RV32I-NEXT: .LBB24_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: and a0, a1, s2
; RV32I-NEXT: mv a2, a1
; RV32I-NEXT: bgeu s3, a0, .LBB24_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB24_2 Depth=1
; RV32I-NEXT: mv a2, s0
; RV32I-NEXT: j .LBB24_1
; RV32I-NEXT: .LBB24_4: # %atomicrmw.end
; RV32I-NEXT: slli a0, a1, 16
; RV32I-NEXT: srai a0, a0, 16
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umin_i16_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a3, 16
; RV32IA-NEXT: addi a3, a3, -1
; RV32IA-NEXT: sll a4, a3, a0
; RV32IA-NEXT: and a1, a1, a3
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a3, (a2)
; RV32IA-NEXT: and a6, a3, a4
; RV32IA-NEXT: mv a5, a3
; RV32IA-NEXT: bgeu a1, a6, .LBB24_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB24_1 Depth=1
; RV32IA-NEXT: xor a5, a3, a1
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a3, a5
; RV32IA-NEXT: .LBB24_3: # in Loop: Header=BB24_1 Depth=1
; RV32IA-NEXT: sc.w a5, a5, (a2)
; RV32IA-NEXT: bnez a5, .LBB24_1
; RV32IA-NEXT: # %bb.4:
; RV32IA-NEXT: srl a0, a3, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umin_i16_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: mv s1, a0
; RV64I-NEXT: lhu a1, 0(a0)
; RV64I-NEXT: lui s2, 16
; RV64I-NEXT: addiw s2, s2, -1
; RV64I-NEXT: and s3, s0, s2
; RV64I-NEXT: j .LBB24_2
; RV64I-NEXT: .LBB24_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB24_2 Depth=1
; RV64I-NEXT: sh a1, 6(sp)
; RV64I-NEXT: addi a1, sp, 6
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: lh a1, 6(sp)
; RV64I-NEXT: bnez a0, .LBB24_4
; RV64I-NEXT: .LBB24_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: and a0, a1, s2
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: bgeu s3, a0, .LBB24_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB24_2 Depth=1
; RV64I-NEXT: mv a2, s0
; RV64I-NEXT: j .LBB24_1
; RV64I-NEXT: .LBB24_4: # %atomicrmw.end
; RV64I-NEXT: slli a0, a1, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umin_i16_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a3, 16
; RV64IA-NEXT: addi a3, a3, -1
; RV64IA-NEXT: sllw a4, a3, a0
; RV64IA-NEXT: and a1, a1, a3
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a3, (a2)
; RV64IA-NEXT: and a6, a3, a4
; RV64IA-NEXT: mv a5, a3
; RV64IA-NEXT: bgeu a1, a6, .LBB24_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB24_1 Depth=1
; RV64IA-NEXT: xor a5, a3, a1
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a3, a5
; RV64IA-NEXT: .LBB24_3: # in Loop: Header=BB24_1 Depth=1
; RV64IA-NEXT: sc.w a5, a5, (a2)
; RV64IA-NEXT: bnez a5, .LBB24_1
; RV64IA-NEXT: # %bb.4:
; RV64IA-NEXT: srlw a0, a3, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = atomicrmw umin ptr %a, i16 %b monotonic
ret i16 %1
}
define signext i32 @atomicrmw_xchg_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_xchg_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_exchange_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xchg_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amoswap.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xchg_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_exchange_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xchg_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoswap.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw xchg ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_add_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_add_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_add_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_add_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amoadd.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_add_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_add_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_add_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoadd.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw add ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_sub_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_sub_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_sub_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_sub_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: neg a1, a1
; RV32IA-NEXT: amoadd.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_sub_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_sub_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_sub_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: neg a1, a1
; RV64IA-NEXT: amoadd.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw sub ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_and_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_and_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_and_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_and_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amoand.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_and_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_and_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_and_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoand.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw and ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_nand_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_nand_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_nand_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-NOZACAS-LABEL: atomicrmw_nand_i32_monotonic:
; RV32IA-NOZACAS: # %bb.0:
; RV32IA-NOZACAS-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NOZACAS-NEXT: lr.w a2, (a0)
; RV32IA-NOZACAS-NEXT: and a3, a2, a1
; RV32IA-NOZACAS-NEXT: not a3, a3
; RV32IA-NOZACAS-NEXT: sc.w a3, a3, (a0)
; RV32IA-NOZACAS-NEXT: bnez a3, .LBB29_1
; RV32IA-NOZACAS-NEXT: # %bb.2:
; RV32IA-NOZACAS-NEXT: mv a0, a2
; RV32IA-NOZACAS-NEXT: ret
;
; RV32IA-ZACAS-LABEL: atomicrmw_nand_i32_monotonic:
; RV32IA-ZACAS: # %bb.0:
; RV32IA-ZACAS-NEXT: mv a2, a0
; RV32IA-ZACAS-NEXT: lw a0, 0(a0)
; RV32IA-ZACAS-NEXT: .LBB29_1: # %atomicrmw.start
; RV32IA-ZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-ZACAS-NEXT: mv a3, a0
; RV32IA-ZACAS-NEXT: and a4, a0, a1
; RV32IA-ZACAS-NEXT: not a4, a4
; RV32IA-ZACAS-NEXT: amocas.w a0, a4, (a2)
; RV32IA-ZACAS-NEXT: bne a0, a3, .LBB29_1
; RV32IA-ZACAS-NEXT: # %bb.2: # %atomicrmw.end
; RV32IA-ZACAS-NEXT: ret
;
; RV64I-LABEL: atomicrmw_nand_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_nand_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: atomicrmw_nand_i32_monotonic:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.w a2, (a0)
; RV64IA-NOZACAS-NEXT: and a3, a2, a1
; RV64IA-NOZACAS-NEXT: not a3, a3
; RV64IA-NOZACAS-NEXT: sc.w a3, a3, (a0)
; RV64IA-NOZACAS-NEXT: bnez a3, .LBB29_1
; RV64IA-NOZACAS-NEXT: # %bb.2:
; RV64IA-NOZACAS-NEXT: mv a0, a2
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: atomicrmw_nand_i32_monotonic:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: mv a2, a0
; RV64IA-ZACAS-NEXT: lw a0, 0(a0)
; RV64IA-ZACAS-NEXT: .LBB29_1: # %atomicrmw.start
; RV64IA-ZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV64IA-ZACAS-NEXT: mv a3, a0
; RV64IA-ZACAS-NEXT: and a4, a0, a1
; RV64IA-ZACAS-NEXT: not a4, a4
; RV64IA-ZACAS-NEXT: amocas.w a0, a4, (a2)
; RV64IA-ZACAS-NEXT: bne a0, a3, .LBB29_1
; RV64IA-ZACAS-NEXT: # %bb.2: # %atomicrmw.end
; RV64IA-ZACAS-NEXT: ret
%1 = atomicrmw nand ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_or_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_or_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_or_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_or_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amoor.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_or_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_or_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_or_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoor.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw or ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_xor_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_xor_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_xor_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xor_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amoxor.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xor_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_xor_4
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xor_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoxor.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw xor ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_max_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_max_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: j .LBB32_2
; RV32I-NEXT: .LBB32_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB32_2 Depth=1
; RV32I-NEXT: sw a3, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a3, 0(sp)
; RV32I-NEXT: bnez a0, .LBB32_4
; RV32I-NEXT: .LBB32_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: blt s1, a3, .LBB32_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB32_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB32_1
; RV32I-NEXT: .LBB32_4: # %atomicrmw.end
; RV32I-NEXT: mv a0, a3
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_max_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amomax.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_max_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lw a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: sext.w s2, a1
; RV64I-NEXT: j .LBB32_2
; RV64I-NEXT: .LBB32_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB32_2 Depth=1
; RV64I-NEXT: sw a3, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a3, 12(sp)
; RV64I-NEXT: bnez a0, .LBB32_4
; RV64I-NEXT: .LBB32_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: blt s2, a3, .LBB32_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB32_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB32_1
; RV64I-NEXT: .LBB32_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_max_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomax.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw max ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_min_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_min_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: j .LBB33_2
; RV32I-NEXT: .LBB33_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB33_2 Depth=1
; RV32I-NEXT: sw a3, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a3, 0(sp)
; RV32I-NEXT: bnez a0, .LBB33_4
; RV32I-NEXT: .LBB33_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bge s1, a3, .LBB33_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB33_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB33_1
; RV32I-NEXT: .LBB33_4: # %atomicrmw.end
; RV32I-NEXT: mv a0, a3
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_min_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amomin.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_min_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lw a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: sext.w s2, a1
; RV64I-NEXT: j .LBB33_2
; RV64I-NEXT: .LBB33_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB33_2 Depth=1
; RV64I-NEXT: sw a3, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a3, 12(sp)
; RV64I-NEXT: bnez a0, .LBB33_4
; RV64I-NEXT: .LBB33_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bge s2, a3, .LBB33_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB33_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB33_1
; RV64I-NEXT: .LBB33_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_min_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomin.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw min ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_umax_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: j .LBB34_2
; RV32I-NEXT: .LBB34_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB34_2 Depth=1
; RV32I-NEXT: sw a3, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a3, 0(sp)
; RV32I-NEXT: bnez a0, .LBB34_4
; RV32I-NEXT: .LBB34_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bltu s1, a3, .LBB34_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB34_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB34_1
; RV32I-NEXT: .LBB34_4: # %atomicrmw.end
; RV32I-NEXT: mv a0, a3
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umax_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amomaxu.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umax_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lw a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: sext.w s2, a1
; RV64I-NEXT: j .LBB34_2
; RV64I-NEXT: .LBB34_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB34_2 Depth=1
; RV64I-NEXT: sw a3, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a3, 12(sp)
; RV64I-NEXT: bnez a0, .LBB34_4
; RV64I-NEXT: .LBB34_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bltu s2, a3, .LBB34_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB34_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB34_1
; RV64I-NEXT: .LBB34_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umax_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomaxu.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw umax ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i32 @atomicrmw_umin_i32_monotonic(ptr %a, i32 %b) nounwind {
; RV32I-LABEL: atomicrmw_umin_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a3, 0(a0)
; RV32I-NEXT: mv s1, a1
; RV32I-NEXT: j .LBB35_2
; RV32I-NEXT: .LBB35_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB35_2 Depth=1
; RV32I-NEXT: sw a3, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a3, 0(sp)
; RV32I-NEXT: bnez a0, .LBB35_4
; RV32I-NEXT: .LBB35_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: bgeu s1, a3, .LBB35_1
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB35_2 Depth=1
; RV32I-NEXT: mv a2, s1
; RV32I-NEXT: j .LBB35_1
; RV32I-NEXT: .LBB35_4: # %atomicrmw.end
; RV32I-NEXT: mv a0, a3
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umin_i32_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: amominu.w a0, a1, (a0)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umin_i32_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: lw a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: sext.w s2, a1
; RV64I-NEXT: j .LBB35_2
; RV64I-NEXT: .LBB35_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB35_2 Depth=1
; RV64I-NEXT: sw a3, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a3, 12(sp)
; RV64I-NEXT: bnez a0, .LBB35_4
; RV64I-NEXT: .LBB35_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bgeu s2, a3, .LBB35_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB35_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB35_1
; RV64I-NEXT: .LBB35_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 48
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umin_i32_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amominu.w a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw umin ptr %a, i32 %b monotonic
ret i32 %1
}
define signext i64 @atomicrmw_xchg_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_xchg_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_exchange_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xchg_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_exchange_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xchg_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_exchange_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xchg_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoswap.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw xchg ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_add_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_add_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_add_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_add_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_add_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_add_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_add_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_add_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoadd.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw add ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_sub_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_sub_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_sub_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_sub_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_sub_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_sub_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_sub_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_sub_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: neg a1, a1
; RV64IA-NEXT: amoadd.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw sub ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_and_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_and_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_and_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_and_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_and_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_and_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_and_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_and_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoand.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw and ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_nand_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_nand_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_nand_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_nand_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_nand_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_nand_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_nand_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: atomicrmw_nand_i64_monotonic:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.d a2, (a0)
; RV64IA-NOZACAS-NEXT: and a3, a2, a1
; RV64IA-NOZACAS-NEXT: not a3, a3
; RV64IA-NOZACAS-NEXT: sc.d a3, a3, (a0)
; RV64IA-NOZACAS-NEXT: bnez a3, .LBB40_1
; RV64IA-NOZACAS-NEXT: # %bb.2:
; RV64IA-NOZACAS-NEXT: mv a0, a2
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: atomicrmw_nand_i64_monotonic:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: mv a2, a0
; RV64IA-ZACAS-NEXT: ld a0, 0(a0)
; RV64IA-ZACAS-NEXT: .LBB40_1: # %atomicrmw.start
; RV64IA-ZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV64IA-ZACAS-NEXT: mv a3, a0
; RV64IA-ZACAS-NEXT: and a4, a0, a1
; RV64IA-ZACAS-NEXT: not a4, a4
; RV64IA-ZACAS-NEXT: amocas.d a0, a4, (a2)
; RV64IA-ZACAS-NEXT: bne a0, a3, .LBB40_1
; RV64IA-ZACAS-NEXT: # %bb.2: # %atomicrmw.end
; RV64IA-ZACAS-NEXT: ret
%1 = atomicrmw nand ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_or_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_or_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_or_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_or_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_or_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_or_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_or_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_or_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoor.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw or ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_xor_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_xor_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: call __atomic_fetch_xor_8
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xor_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -16
; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IA-NEXT: li a3, 0
; RV32IA-NEXT: call __atomic_fetch_xor_8
; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xor_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_xor_8
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xor_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amoxor.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw xor ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_max_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_max_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a5, 4(a0)
; RV32I-NEXT: lw a4, 0(a0)
; RV32I-NEXT: mv s1, a2
; RV32I-NEXT: mv s2, a1
; RV32I-NEXT: j .LBB43_2
; RV32I-NEXT: .LBB43_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32I-NEXT: sw a4, 8(sp)
; RV32I-NEXT: sw a5, 12(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: li a5, 0
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw a5, 12(sp)
; RV32I-NEXT: lw a4, 8(sp)
; RV32I-NEXT: bnez a0, .LBB43_7
; RV32I-NEXT: .LBB43_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: beq a5, s1, .LBB43_4
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32I-NEXT: slt a0, s1, a5
; RV32I-NEXT: j .LBB43_5
; RV32I-NEXT: .LBB43_4: # in Loop: Header=BB43_2 Depth=1
; RV32I-NEXT: sltu a0, s2, a4
; RV32I-NEXT: .LBB43_5: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32I-NEXT: mv a2, a4
; RV32I-NEXT: mv a3, a5
; RV32I-NEXT: bnez a0, .LBB43_1
; RV32I-NEXT: # %bb.6: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32I-NEXT: mv a2, s2
; RV32I-NEXT: mv a3, s1
; RV32I-NEXT: j .LBB43_1
; RV32I-NEXT: .LBB43_7: # %atomicrmw.end
; RV32I-NEXT: mv a0, a4
; RV32I-NEXT: mv a1, a5
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_max_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -32
; RV32IA-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32IA-NEXT: mv s0, a0
; RV32IA-NEXT: lw a5, 4(a0)
; RV32IA-NEXT: lw a4, 0(a0)
; RV32IA-NEXT: mv s1, a2
; RV32IA-NEXT: mv s2, a1
; RV32IA-NEXT: j .LBB43_2
; RV32IA-NEXT: .LBB43_1: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32IA-NEXT: sw a4, 8(sp)
; RV32IA-NEXT: sw a5, 12(sp)
; RV32IA-NEXT: addi a1, sp, 8
; RV32IA-NEXT: mv a0, s0
; RV32IA-NEXT: li a4, 0
; RV32IA-NEXT: li a5, 0
; RV32IA-NEXT: call __atomic_compare_exchange_8
; RV32IA-NEXT: lw a5, 12(sp)
; RV32IA-NEXT: lw a4, 8(sp)
; RV32IA-NEXT: bnez a0, .LBB43_7
; RV32IA-NEXT: .LBB43_2: # %atomicrmw.start
; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: beq a5, s1, .LBB43_4
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32IA-NEXT: slt a0, s1, a5
; RV32IA-NEXT: j .LBB43_5
; RV32IA-NEXT: .LBB43_4: # in Loop: Header=BB43_2 Depth=1
; RV32IA-NEXT: sltu a0, s2, a4
; RV32IA-NEXT: .LBB43_5: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32IA-NEXT: mv a2, a4
; RV32IA-NEXT: mv a3, a5
; RV32IA-NEXT: bnez a0, .LBB43_1
; RV32IA-NEXT: # %bb.6: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV32IA-NEXT: mv a2, s2
; RV32IA-NEXT: mv a3, s1
; RV32IA-NEXT: j .LBB43_1
; RV32IA-NEXT: .LBB43_7: # %atomicrmw.end
; RV32IA-NEXT: mv a0, a4
; RV32IA-NEXT: mv a1, a5
; RV32IA-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 32
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_max_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: ld a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: j .LBB43_2
; RV64I-NEXT: .LBB43_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV64I-NEXT: sd a3, 0(sp)
; RV64I-NEXT: mv a1, sp
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_8
; RV64I-NEXT: ld a3, 0(sp)
; RV64I-NEXT: bnez a0, .LBB43_4
; RV64I-NEXT: .LBB43_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: blt s1, a3, .LBB43_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB43_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB43_1
; RV64I-NEXT: .LBB43_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_max_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomax.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw max ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_min_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_min_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a5, 4(a0)
; RV32I-NEXT: lw a4, 0(a0)
; RV32I-NEXT: mv s1, a2
; RV32I-NEXT: mv s2, a1
; RV32I-NEXT: j .LBB44_2
; RV32I-NEXT: .LBB44_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32I-NEXT: sw a4, 8(sp)
; RV32I-NEXT: sw a5, 12(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: li a5, 0
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw a5, 12(sp)
; RV32I-NEXT: lw a4, 8(sp)
; RV32I-NEXT: bnez a0, .LBB44_7
; RV32I-NEXT: .LBB44_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: beq a5, s1, .LBB44_4
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32I-NEXT: slt a0, s1, a5
; RV32I-NEXT: j .LBB44_5
; RV32I-NEXT: .LBB44_4: # in Loop: Header=BB44_2 Depth=1
; RV32I-NEXT: sltu a0, s2, a4
; RV32I-NEXT: .LBB44_5: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32I-NEXT: mv a2, a4
; RV32I-NEXT: mv a3, a5
; RV32I-NEXT: beqz a0, .LBB44_1
; RV32I-NEXT: # %bb.6: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32I-NEXT: mv a2, s2
; RV32I-NEXT: mv a3, s1
; RV32I-NEXT: j .LBB44_1
; RV32I-NEXT: .LBB44_7: # %atomicrmw.end
; RV32I-NEXT: mv a0, a4
; RV32I-NEXT: mv a1, a5
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_min_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -32
; RV32IA-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32IA-NEXT: mv s0, a0
; RV32IA-NEXT: lw a5, 4(a0)
; RV32IA-NEXT: lw a4, 0(a0)
; RV32IA-NEXT: mv s1, a2
; RV32IA-NEXT: mv s2, a1
; RV32IA-NEXT: j .LBB44_2
; RV32IA-NEXT: .LBB44_1: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32IA-NEXT: sw a4, 8(sp)
; RV32IA-NEXT: sw a5, 12(sp)
; RV32IA-NEXT: addi a1, sp, 8
; RV32IA-NEXT: mv a0, s0
; RV32IA-NEXT: li a4, 0
; RV32IA-NEXT: li a5, 0
; RV32IA-NEXT: call __atomic_compare_exchange_8
; RV32IA-NEXT: lw a5, 12(sp)
; RV32IA-NEXT: lw a4, 8(sp)
; RV32IA-NEXT: bnez a0, .LBB44_7
; RV32IA-NEXT: .LBB44_2: # %atomicrmw.start
; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: beq a5, s1, .LBB44_4
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32IA-NEXT: slt a0, s1, a5
; RV32IA-NEXT: j .LBB44_5
; RV32IA-NEXT: .LBB44_4: # in Loop: Header=BB44_2 Depth=1
; RV32IA-NEXT: sltu a0, s2, a4
; RV32IA-NEXT: .LBB44_5: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32IA-NEXT: mv a2, a4
; RV32IA-NEXT: mv a3, a5
; RV32IA-NEXT: beqz a0, .LBB44_1
; RV32IA-NEXT: # %bb.6: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV32IA-NEXT: mv a2, s2
; RV32IA-NEXT: mv a3, s1
; RV32IA-NEXT: j .LBB44_1
; RV32IA-NEXT: .LBB44_7: # %atomicrmw.end
; RV32IA-NEXT: mv a0, a4
; RV32IA-NEXT: mv a1, a5
; RV32IA-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 32
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_min_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: ld a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: j .LBB44_2
; RV64I-NEXT: .LBB44_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV64I-NEXT: sd a3, 0(sp)
; RV64I-NEXT: mv a1, sp
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_8
; RV64I-NEXT: ld a3, 0(sp)
; RV64I-NEXT: bnez a0, .LBB44_4
; RV64I-NEXT: .LBB44_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bge s1, a3, .LBB44_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB44_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB44_1
; RV64I-NEXT: .LBB44_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_min_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomin.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw min ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_umax_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_umax_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a5, 4(a0)
; RV32I-NEXT: lw a4, 0(a0)
; RV32I-NEXT: mv s1, a2
; RV32I-NEXT: mv s2, a1
; RV32I-NEXT: j .LBB45_2
; RV32I-NEXT: .LBB45_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32I-NEXT: sw a4, 8(sp)
; RV32I-NEXT: sw a5, 12(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: li a5, 0
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw a5, 12(sp)
; RV32I-NEXT: lw a4, 8(sp)
; RV32I-NEXT: bnez a0, .LBB45_7
; RV32I-NEXT: .LBB45_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: beq a5, s1, .LBB45_4
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32I-NEXT: sltu a0, s1, a5
; RV32I-NEXT: j .LBB45_5
; RV32I-NEXT: .LBB45_4: # in Loop: Header=BB45_2 Depth=1
; RV32I-NEXT: sltu a0, s2, a4
; RV32I-NEXT: .LBB45_5: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32I-NEXT: mv a2, a4
; RV32I-NEXT: mv a3, a5
; RV32I-NEXT: bnez a0, .LBB45_1
; RV32I-NEXT: # %bb.6: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32I-NEXT: mv a2, s2
; RV32I-NEXT: mv a3, s1
; RV32I-NEXT: j .LBB45_1
; RV32I-NEXT: .LBB45_7: # %atomicrmw.end
; RV32I-NEXT: mv a0, a4
; RV32I-NEXT: mv a1, a5
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umax_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -32
; RV32IA-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32IA-NEXT: mv s0, a0
; RV32IA-NEXT: lw a5, 4(a0)
; RV32IA-NEXT: lw a4, 0(a0)
; RV32IA-NEXT: mv s1, a2
; RV32IA-NEXT: mv s2, a1
; RV32IA-NEXT: j .LBB45_2
; RV32IA-NEXT: .LBB45_1: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32IA-NEXT: sw a4, 8(sp)
; RV32IA-NEXT: sw a5, 12(sp)
; RV32IA-NEXT: addi a1, sp, 8
; RV32IA-NEXT: mv a0, s0
; RV32IA-NEXT: li a4, 0
; RV32IA-NEXT: li a5, 0
; RV32IA-NEXT: call __atomic_compare_exchange_8
; RV32IA-NEXT: lw a5, 12(sp)
; RV32IA-NEXT: lw a4, 8(sp)
; RV32IA-NEXT: bnez a0, .LBB45_7
; RV32IA-NEXT: .LBB45_2: # %atomicrmw.start
; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: beq a5, s1, .LBB45_4
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32IA-NEXT: sltu a0, s1, a5
; RV32IA-NEXT: j .LBB45_5
; RV32IA-NEXT: .LBB45_4: # in Loop: Header=BB45_2 Depth=1
; RV32IA-NEXT: sltu a0, s2, a4
; RV32IA-NEXT: .LBB45_5: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32IA-NEXT: mv a2, a4
; RV32IA-NEXT: mv a3, a5
; RV32IA-NEXT: bnez a0, .LBB45_1
; RV32IA-NEXT: # %bb.6: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV32IA-NEXT: mv a2, s2
; RV32IA-NEXT: mv a3, s1
; RV32IA-NEXT: j .LBB45_1
; RV32IA-NEXT: .LBB45_7: # %atomicrmw.end
; RV32IA-NEXT: mv a0, a4
; RV32IA-NEXT: mv a1, a5
; RV32IA-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 32
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umax_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: ld a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: j .LBB45_2
; RV64I-NEXT: .LBB45_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV64I-NEXT: sd a3, 0(sp)
; RV64I-NEXT: mv a1, sp
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_8
; RV64I-NEXT: ld a3, 0(sp)
; RV64I-NEXT: bnez a0, .LBB45_4
; RV64I-NEXT: .LBB45_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bltu s1, a3, .LBB45_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB45_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB45_1
; RV64I-NEXT: .LBB45_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umax_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amomaxu.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw umax ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i64 @atomicrmw_umin_i64_monotonic(ptr %a, i64 %b) nounwind {
; RV32I-LABEL: atomicrmw_umin_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: lw a5, 4(a0)
; RV32I-NEXT: lw a4, 0(a0)
; RV32I-NEXT: mv s1, a2
; RV32I-NEXT: mv s2, a1
; RV32I-NEXT: j .LBB46_2
; RV32I-NEXT: .LBB46_1: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32I-NEXT: sw a4, 8(sp)
; RV32I-NEXT: sw a5, 12(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: li a5, 0
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw a5, 12(sp)
; RV32I-NEXT: lw a4, 8(sp)
; RV32I-NEXT: bnez a0, .LBB46_7
; RV32I-NEXT: .LBB46_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: beq a5, s1, .LBB46_4
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32I-NEXT: sltu a0, s1, a5
; RV32I-NEXT: j .LBB46_5
; RV32I-NEXT: .LBB46_4: # in Loop: Header=BB46_2 Depth=1
; RV32I-NEXT: sltu a0, s2, a4
; RV32I-NEXT: .LBB46_5: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32I-NEXT: mv a2, a4
; RV32I-NEXT: mv a3, a5
; RV32I-NEXT: beqz a0, .LBB46_1
; RV32I-NEXT: # %bb.6: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32I-NEXT: mv a2, s2
; RV32I-NEXT: mv a3, s1
; RV32I-NEXT: j .LBB46_1
; RV32I-NEXT: .LBB46_7: # %atomicrmw.end
; RV32I-NEXT: mv a0, a4
; RV32I-NEXT: mv a1, a5
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umin_i64_monotonic:
; RV32IA: # %bb.0:
; RV32IA-NEXT: addi sp, sp, -32
; RV32IA-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
; RV32IA-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
; RV32IA-NEXT: mv s0, a0
; RV32IA-NEXT: lw a5, 4(a0)
; RV32IA-NEXT: lw a4, 0(a0)
; RV32IA-NEXT: mv s1, a2
; RV32IA-NEXT: mv s2, a1
; RV32IA-NEXT: j .LBB46_2
; RV32IA-NEXT: .LBB46_1: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32IA-NEXT: sw a4, 8(sp)
; RV32IA-NEXT: sw a5, 12(sp)
; RV32IA-NEXT: addi a1, sp, 8
; RV32IA-NEXT: mv a0, s0
; RV32IA-NEXT: li a4, 0
; RV32IA-NEXT: li a5, 0
; RV32IA-NEXT: call __atomic_compare_exchange_8
; RV32IA-NEXT: lw a5, 12(sp)
; RV32IA-NEXT: lw a4, 8(sp)
; RV32IA-NEXT: bnez a0, .LBB46_7
; RV32IA-NEXT: .LBB46_2: # %atomicrmw.start
; RV32IA-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: beq a5, s1, .LBB46_4
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32IA-NEXT: sltu a0, s1, a5
; RV32IA-NEXT: j .LBB46_5
; RV32IA-NEXT: .LBB46_4: # in Loop: Header=BB46_2 Depth=1
; RV32IA-NEXT: sltu a0, s2, a4
; RV32IA-NEXT: .LBB46_5: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32IA-NEXT: mv a2, a4
; RV32IA-NEXT: mv a3, a5
; RV32IA-NEXT: beqz a0, .LBB46_1
; RV32IA-NEXT: # %bb.6: # %atomicrmw.start
; RV32IA-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV32IA-NEXT: mv a2, s2
; RV32IA-NEXT: mv a3, s1
; RV32IA-NEXT: j .LBB46_1
; RV32IA-NEXT: .LBB46_7: # %atomicrmw.end
; RV32IA-NEXT: mv a0, a4
; RV32IA-NEXT: mv a1, a5
; RV32IA-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32IA-NEXT: addi sp, sp, 32
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umin_i64_monotonic:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: ld a3, 0(a0)
; RV64I-NEXT: mv s1, a1
; RV64I-NEXT: j .LBB46_2
; RV64I-NEXT: .LBB46_1: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV64I-NEXT: sd a3, 0(sp)
; RV64I-NEXT: mv a1, sp
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_8
; RV64I-NEXT: ld a3, 0(sp)
; RV64I-NEXT: bnez a0, .LBB46_4
; RV64I-NEXT: .LBB46_2: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a3
; RV64I-NEXT: bgeu s1, a3, .LBB46_1
; RV64I-NEXT: # %bb.3: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB46_2 Depth=1
; RV64I-NEXT: mv a2, s1
; RV64I-NEXT: j .LBB46_1
; RV64I-NEXT: .LBB46_4: # %atomicrmw.end
; RV64I-NEXT: mv a0, a3
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umin_i64_monotonic:
; RV64IA: # %bb.0:
; RV64IA-NEXT: amominu.d a0, a1, (a0)
; RV64IA-NEXT: ret
%1 = atomicrmw umin ptr %a, i64 %b monotonic
ret i64 %1
}
define signext i8 @cmpxchg_i8_monotonic_monotonic_val0(ptr %ptr, i8 signext %cmp, i8 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i8_monotonic_monotonic_val0:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lb a0, 11(sp)
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: cmpxchg_i8_monotonic_monotonic_val0:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a3, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a4, 255
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: andi a2, a2, 255
; RV32IA-NEXT: sll a2, a2, a0
; RV32IA-NEXT: .LBB47_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a5, (a3)
; RV32IA-NEXT: and a6, a5, a4
; RV32IA-NEXT: bne a6, a1, .LBB47_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB47_1 Depth=1
; RV32IA-NEXT: xor a6, a5, a2
; RV32IA-NEXT: and a6, a6, a4
; RV32IA-NEXT: xor a6, a5, a6
; RV32IA-NEXT: sc.w a6, a6, (a3)
; RV32IA-NEXT: bnez a6, .LBB47_1
; RV32IA-NEXT: .LBB47_3:
; RV32IA-NEXT: srl a0, a5, a0
; RV32IA-NEXT: slli a0, a0, 24
; RV32IA-NEXT: srai a0, a0, 24
; RV32IA-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i8_monotonic_monotonic_val0:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sb a1, 7(sp)
; RV64I-NEXT: addi a1, sp, 7
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: lb a0, 7(sp)
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: cmpxchg_i8_monotonic_monotonic_val0:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a3, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a4, 255
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: andi a2, a2, 255
; RV64IA-NEXT: sllw a2, a2, a0
; RV64IA-NEXT: .LBB47_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a5, (a3)
; RV64IA-NEXT: and a6, a5, a4
; RV64IA-NEXT: bne a6, a1, .LBB47_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB47_1 Depth=1
; RV64IA-NEXT: xor a6, a5, a2
; RV64IA-NEXT: and a6, a6, a4
; RV64IA-NEXT: xor a6, a5, a6
; RV64IA-NEXT: sc.w a6, a6, (a3)
; RV64IA-NEXT: bnez a6, .LBB47_1
; RV64IA-NEXT: .LBB47_3:
; RV64IA-NEXT: srlw a0, a5, a0
; RV64IA-NEXT: slli a0, a0, 56
; RV64IA-NEXT: srai a0, a0, 56
; RV64IA-NEXT: ret
%1 = cmpxchg ptr %ptr, i8 %cmp, i8 %val monotonic monotonic
%2 = extractvalue { i8, i1 } %1, 0
ret i8 %2
}
define i1 @cmpxchg_i8_monotonic_monotonic_val1(ptr %ptr, i8 signext %cmp, i8 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i8_monotonic_monotonic_val1:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: cmpxchg_i8_monotonic_monotonic_val1:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a3, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: li a4, 255
; RV32IA-NEXT: sll a4, a4, a0
; RV32IA-NEXT: andi a1, a1, 255
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: andi a2, a2, 255
; RV32IA-NEXT: sll a0, a2, a0
; RV32IA-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a2, (a3)
; RV32IA-NEXT: and a5, a2, a4
; RV32IA-NEXT: bne a5, a1, .LBB48_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB48_1 Depth=1
; RV32IA-NEXT: xor a5, a2, a0
; RV32IA-NEXT: and a5, a5, a4
; RV32IA-NEXT: xor a5, a2, a5
; RV32IA-NEXT: sc.w a5, a5, (a3)
; RV32IA-NEXT: bnez a5, .LBB48_1
; RV32IA-NEXT: .LBB48_3:
; RV32IA-NEXT: and a2, a2, a4
; RV32IA-NEXT: xor a1, a1, a2
; RV32IA-NEXT: seqz a0, a1
; RV32IA-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i8_monotonic_monotonic_val1:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sb a1, 7(sp)
; RV64I-NEXT: addi a1, sp, 7
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_1
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: cmpxchg_i8_monotonic_monotonic_val1:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a3, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: li a4, 255
; RV64IA-NEXT: sllw a4, a4, a0
; RV64IA-NEXT: andi a1, a1, 255
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: andi a2, a2, 255
; RV64IA-NEXT: sllw a0, a2, a0
; RV64IA-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a2, (a3)
; RV64IA-NEXT: and a5, a2, a4
; RV64IA-NEXT: bne a5, a1, .LBB48_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB48_1 Depth=1
; RV64IA-NEXT: xor a5, a2, a0
; RV64IA-NEXT: and a5, a5, a4
; RV64IA-NEXT: xor a5, a2, a5
; RV64IA-NEXT: sc.w a5, a5, (a3)
; RV64IA-NEXT: bnez a5, .LBB48_1
; RV64IA-NEXT: .LBB48_3:
; RV64IA-NEXT: and a2, a2, a4
; RV64IA-NEXT: xor a1, a1, a2
; RV64IA-NEXT: seqz a0, a1
; RV64IA-NEXT: ret
%1 = cmpxchg ptr %ptr, i8 %cmp, i8 %val monotonic monotonic
%2 = extractvalue { i8, i1 } %1, 1
ret i1 %2
}
define signext i16 @cmpxchg_i16_monotonic_monotonic_val0(ptr %ptr, i16 signext %cmp, i16 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i16_monotonic_monotonic_val0:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lh a0, 10(sp)
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: cmpxchg_i16_monotonic_monotonic_val0:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a3, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a4, 16
; RV32IA-NEXT: addi a4, a4, -1
; RV32IA-NEXT: sll a5, a4, a0
; RV32IA-NEXT: and a1, a1, a4
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: and a2, a2, a4
; RV32IA-NEXT: sll a2, a2, a0
; RV32IA-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a4, (a3)
; RV32IA-NEXT: and a6, a4, a5
; RV32IA-NEXT: bne a6, a1, .LBB49_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB49_1 Depth=1
; RV32IA-NEXT: xor a6, a4, a2
; RV32IA-NEXT: and a6, a6, a5
; RV32IA-NEXT: xor a6, a4, a6
; RV32IA-NEXT: sc.w a6, a6, (a3)
; RV32IA-NEXT: bnez a6, .LBB49_1
; RV32IA-NEXT: .LBB49_3:
; RV32IA-NEXT: srl a0, a4, a0
; RV32IA-NEXT: slli a0, a0, 16
; RV32IA-NEXT: srai a0, a0, 16
; RV32IA-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i16_monotonic_monotonic_val0:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sh a1, 6(sp)
; RV64I-NEXT: addi a1, sp, 6
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: lh a0, 6(sp)
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: cmpxchg_i16_monotonic_monotonic_val0:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a3, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a4, 16
; RV64IA-NEXT: addi a4, a4, -1
; RV64IA-NEXT: sllw a5, a4, a0
; RV64IA-NEXT: and a1, a1, a4
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: and a2, a2, a4
; RV64IA-NEXT: sllw a2, a2, a0
; RV64IA-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a4, (a3)
; RV64IA-NEXT: and a6, a4, a5
; RV64IA-NEXT: bne a6, a1, .LBB49_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB49_1 Depth=1
; RV64IA-NEXT: xor a6, a4, a2
; RV64IA-NEXT: and a6, a6, a5
; RV64IA-NEXT: xor a6, a4, a6
; RV64IA-NEXT: sc.w a6, a6, (a3)
; RV64IA-NEXT: bnez a6, .LBB49_1
; RV64IA-NEXT: .LBB49_3:
; RV64IA-NEXT: srlw a0, a4, a0
; RV64IA-NEXT: slli a0, a0, 48
; RV64IA-NEXT: srai a0, a0, 48
; RV64IA-NEXT: ret
%1 = cmpxchg ptr %ptr, i16 %cmp, i16 %val monotonic monotonic
%2 = extractvalue { i16, i1 } %1, 0
ret i16 %2
}
define i1 @cmpxchg_i16_monotonic_monotonic_val1(ptr %ptr, i16 signext %cmp, i16 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i16_monotonic_monotonic_val1:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: cmpxchg_i16_monotonic_monotonic_val1:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a3, a0, -4
; RV32IA-NEXT: slli a0, a0, 3
; RV32IA-NEXT: lui a4, 16
; RV32IA-NEXT: addi a4, a4, -1
; RV32IA-NEXT: sll a5, a4, a0
; RV32IA-NEXT: and a1, a1, a4
; RV32IA-NEXT: sll a1, a1, a0
; RV32IA-NEXT: and a2, a2, a4
; RV32IA-NEXT: sll a0, a2, a0
; RV32IA-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NEXT: lr.w a2, (a3)
; RV32IA-NEXT: and a4, a2, a5
; RV32IA-NEXT: bne a4, a1, .LBB50_3
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB50_1 Depth=1
; RV32IA-NEXT: xor a4, a2, a0
; RV32IA-NEXT: and a4, a4, a5
; RV32IA-NEXT: xor a4, a2, a4
; RV32IA-NEXT: sc.w a4, a4, (a3)
; RV32IA-NEXT: bnez a4, .LBB50_1
; RV32IA-NEXT: .LBB50_3:
; RV32IA-NEXT: and a2, a2, a5
; RV32IA-NEXT: xor a1, a1, a2
; RV32IA-NEXT: seqz a0, a1
; RV32IA-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i16_monotonic_monotonic_val1:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sh a1, 6(sp)
; RV64I-NEXT: addi a1, sp, 6
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_2
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-LABEL: cmpxchg_i16_monotonic_monotonic_val1:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a3, a0, -4
; RV64IA-NEXT: slli a0, a0, 3
; RV64IA-NEXT: lui a4, 16
; RV64IA-NEXT: addi a4, a4, -1
; RV64IA-NEXT: sllw a5, a4, a0
; RV64IA-NEXT: and a1, a1, a4
; RV64IA-NEXT: sllw a1, a1, a0
; RV64IA-NEXT: and a2, a2, a4
; RV64IA-NEXT: sllw a0, a2, a0
; RV64IA-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NEXT: lr.w a2, (a3)
; RV64IA-NEXT: and a4, a2, a5
; RV64IA-NEXT: bne a4, a1, .LBB50_3
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB50_1 Depth=1
; RV64IA-NEXT: xor a4, a2, a0
; RV64IA-NEXT: and a4, a4, a5
; RV64IA-NEXT: xor a4, a2, a4
; RV64IA-NEXT: sc.w a4, a4, (a3)
; RV64IA-NEXT: bnez a4, .LBB50_1
; RV64IA-NEXT: .LBB50_3:
; RV64IA-NEXT: and a2, a2, a5
; RV64IA-NEXT: xor a1, a1, a2
; RV64IA-NEXT: seqz a0, a1
; RV64IA-NEXT: ret
%1 = cmpxchg ptr %ptr, i16 %cmp, i16 %val monotonic monotonic
%2 = extractvalue { i16, i1 } %1, 1
ret i1 %2
}
define signext i32 @cmpxchg_i32_monotonic_monotonic_val0(ptr %ptr, i32 signext %cmp, i32 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a0, 8(sp)
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV32IA-NOZACAS: # %bb.0:
; RV32IA-NOZACAS-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NOZACAS-NEXT: lr.w a3, (a0)
; RV32IA-NOZACAS-NEXT: bne a3, a1, .LBB51_3
; RV32IA-NOZACAS-NEXT: # %bb.2: # in Loop: Header=BB51_1 Depth=1
; RV32IA-NOZACAS-NEXT: sc.w a4, a2, (a0)
; RV32IA-NOZACAS-NEXT: bnez a4, .LBB51_1
; RV32IA-NOZACAS-NEXT: .LBB51_3:
; RV32IA-NOZACAS-NEXT: mv a0, a3
; RV32IA-NOZACAS-NEXT: ret
;
; RV32IA-ZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV32IA-ZACAS: # %bb.0:
; RV32IA-ZACAS-NEXT: amocas.w a1, a2, (a0)
; RV32IA-ZACAS-NEXT: mv a0, a1
; RV32IA-ZACAS-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sw a1, 4(sp)
; RV64I-NEXT: addi a1, sp, 4
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a0, 4(sp)
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.w a3, (a0)
; RV64IA-NOZACAS-NEXT: bne a3, a1, .LBB51_3
; RV64IA-NOZACAS-NEXT: # %bb.2: # in Loop: Header=BB51_1 Depth=1
; RV64IA-NOZACAS-NEXT: sc.w a4, a2, (a0)
; RV64IA-NOZACAS-NEXT: bnez a4, .LBB51_1
; RV64IA-NOZACAS-NEXT: .LBB51_3:
; RV64IA-NOZACAS-NEXT: mv a0, a3
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val0:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: amocas.w a1, a2, (a0)
; RV64IA-ZACAS-NEXT: mv a0, a1
; RV64IA-ZACAS-NEXT: ret
%1 = cmpxchg ptr %ptr, i32 %cmp, i32 %val monotonic monotonic
%2 = extractvalue { i32, i1 } %1, 0
ret i32 %2
}
define i1 @cmpxchg_i32_monotonic_monotonic_val1(ptr %ptr, i32 signext %cmp, i32 signext %val) nounwind {
; RV32I-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV32IA-NOZACAS: # %bb.0:
; RV32IA-NOZACAS-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1
; RV32IA-NOZACAS-NEXT: lr.w a3, (a0)
; RV32IA-NOZACAS-NEXT: bne a3, a1, .LBB52_3
; RV32IA-NOZACAS-NEXT: # %bb.2: # in Loop: Header=BB52_1 Depth=1
; RV32IA-NOZACAS-NEXT: sc.w a4, a2, (a0)
; RV32IA-NOZACAS-NEXT: bnez a4, .LBB52_1
; RV32IA-NOZACAS-NEXT: .LBB52_3:
; RV32IA-NOZACAS-NEXT: xor a1, a3, a1
; RV32IA-NOZACAS-NEXT: seqz a0, a1
; RV32IA-NOZACAS-NEXT: ret
;
; RV32IA-ZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV32IA-ZACAS: # %bb.0:
; RV32IA-ZACAS-NEXT: mv a3, a1
; RV32IA-ZACAS-NEXT: amocas.w a3, a2, (a0)
; RV32IA-ZACAS-NEXT: xor a1, a3, a1
; RV32IA-ZACAS-NEXT: seqz a0, a1
; RV32IA-ZACAS-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sw a1, 4(sp)
; RV64I-NEXT: addi a1, sp, 4
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.w a3, (a0)
; RV64IA-NOZACAS-NEXT: bne a3, a1, .LBB52_3
; RV64IA-NOZACAS-NEXT: # %bb.2: # in Loop: Header=BB52_1 Depth=1
; RV64IA-NOZACAS-NEXT: sc.w a4, a2, (a0)
; RV64IA-NOZACAS-NEXT: bnez a4, .LBB52_1
; RV64IA-NOZACAS-NEXT: .LBB52_3:
; RV64IA-NOZACAS-NEXT: xor a1, a3, a1
; RV64IA-NOZACAS-NEXT: seqz a0, a1
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: cmpxchg_i32_monotonic_monotonic_val1:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: mv a3, a1
; RV64IA-ZACAS-NEXT: amocas.w a3, a2, (a0)
; RV64IA-ZACAS-NEXT: xor a1, a3, a1
; RV64IA-ZACAS-NEXT: seqz a0, a1
; RV64IA-ZACAS-NEXT: ret
%1 = cmpxchg ptr %ptr, i32 %cmp, i32 %val monotonic monotonic
%2 = extractvalue { i32, i1 } %1, 1
ret i1 %2
}
define signext i32 @atomicrmw_xchg_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_xchg_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB53_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_exchange_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB53_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: li a2, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xchg_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB53_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amoswap.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB53_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: li a2, 1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xchg_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB53_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_exchange_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB53_2: # %else
; RV64I-NEXT: lw a1, 0(a0)
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xchg_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB53_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amoswap.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB53_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: li a2, 1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw xchg ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
store i32 1, ptr %a
br label %merge
merge:
%3 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %3
}
define signext i32 @atomicrmw_add_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_add_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB54_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_add_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB54_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: addi a2, a1, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_add_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB54_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amoadd.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB54_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: addi a2, a0, 1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_add_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB54_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_add_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB54_2: # %else
; RV64I-NEXT: lw a1, 0(a0)
; RV64I-NEXT: addi a2, a1, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_add_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB54_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amoadd.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB54_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: addi a2, a0, 1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw add ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = add i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_sub_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_sub_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB55_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_sub_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB55_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: addi a2, a1, -1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_sub_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB55_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, -1
; RV32IA-NEXT: amoadd.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB55_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: addi a2, a0, -1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_sub_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB55_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_sub_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB55_2: # %else
; RV64I-NEXT: lw a1, 0(a0)
; RV64I-NEXT: addi a2, a1, -1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_sub_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB55_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, -1
; RV64IA-NEXT: amoadd.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB55_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: addi a2, a0, -1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw sub ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = sub i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_and_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_and_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB56_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_and_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB56_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: andi a2, a1, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_and_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB56_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amoand.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB56_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: andi a2, a0, 1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_and_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB56_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_and_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB56_2: # %else
; RV64I-NEXT: lwu a1, 0(a0)
; RV64I-NEXT: andi a2, a1, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_and_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB56_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amoand.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB56_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: andi a2, a0, 1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw and ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = and i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_nand_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB57_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_nand_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB57_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: andi a2, a1, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-NOZACAS-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV32IA-NOZACAS: # %bb.0:
; RV32IA-NOZACAS-NEXT: andi a2, a1, 1
; RV32IA-NOZACAS-NEXT: mv a1, a0
; RV32IA-NOZACAS-NEXT: beqz a2, .LBB57_2
; RV32IA-NOZACAS-NEXT: # %bb.1: # %then
; RV32IA-NOZACAS-NEXT: li a2, 1
; RV32IA-NOZACAS-NEXT: .LBB57_3: # %then
; RV32IA-NOZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NOZACAS-NEXT: lr.w a0, (a1)
; RV32IA-NOZACAS-NEXT: and a3, a0, a2
; RV32IA-NOZACAS-NEXT: not a3, a3
; RV32IA-NOZACAS-NEXT: sc.w a3, a3, (a1)
; RV32IA-NOZACAS-NEXT: bnez a3, .LBB57_3
; RV32IA-NOZACAS-NEXT: # %bb.4: # %then
; RV32IA-NOZACAS-NEXT: ret
; RV32IA-NOZACAS-NEXT: .LBB57_2: # %else
; RV32IA-NOZACAS-NEXT: lw a0, 0(a1)
; RV32IA-NOZACAS-NEXT: andi a2, a0, 1
; RV32IA-NOZACAS-NEXT: sw a2, 0(a1)
; RV32IA-NOZACAS-NEXT: ret
;
; RV32IA-ZACAS-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV32IA-ZACAS: # %bb.0:
; RV32IA-ZACAS-NEXT: andi a1, a1, 1
; RV32IA-ZACAS-NEXT: beqz a1, .LBB57_4
; RV32IA-ZACAS-NEXT: # %bb.1: # %then
; RV32IA-ZACAS-NEXT: lw a1, 0(a0)
; RV32IA-ZACAS-NEXT: .LBB57_2: # %atomicrmw.start
; RV32IA-ZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-ZACAS-NEXT: mv a2, a1
; RV32IA-ZACAS-NEXT: not a3, a1
; RV32IA-ZACAS-NEXT: ori a3, a3, -2
; RV32IA-ZACAS-NEXT: amocas.w a1, a3, (a0)
; RV32IA-ZACAS-NEXT: bne a1, a2, .LBB57_2
; RV32IA-ZACAS-NEXT: # %bb.3: # %merge
; RV32IA-ZACAS-NEXT: mv a0, a1
; RV32IA-ZACAS-NEXT: ret
; RV32IA-ZACAS-NEXT: .LBB57_4: # %else
; RV32IA-ZACAS-NEXT: lw a1, 0(a0)
; RV32IA-ZACAS-NEXT: andi a2, a1, 1
; RV32IA-ZACAS-NEXT: sw a2, 0(a0)
; RV32IA-ZACAS-NEXT: mv a0, a1
; RV32IA-ZACAS-NEXT: ret
;
; RV64I-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB57_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_nand_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB57_2: # %else
; RV64I-NEXT: lwu a1, 0(a0)
; RV64I-NEXT: andi a2, a1, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: andi a2, a1, 1
; RV64IA-NOZACAS-NEXT: mv a1, a0
; RV64IA-NOZACAS-NEXT: beqz a2, .LBB57_2
; RV64IA-NOZACAS-NEXT: # %bb.1: # %then
; RV64IA-NOZACAS-NEXT: li a2, 1
; RV64IA-NOZACAS-NEXT: .LBB57_3: # %then
; RV64IA-NOZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.w a0, (a1)
; RV64IA-NOZACAS-NEXT: and a3, a0, a2
; RV64IA-NOZACAS-NEXT: not a3, a3
; RV64IA-NOZACAS-NEXT: sc.w a3, a3, (a1)
; RV64IA-NOZACAS-NEXT: bnez a3, .LBB57_3
; RV64IA-NOZACAS-NEXT: # %bb.4: # %then
; RV64IA-NOZACAS-NEXT: ret
; RV64IA-NOZACAS-NEXT: .LBB57_2: # %else
; RV64IA-NOZACAS-NEXT: lw a0, 0(a1)
; RV64IA-NOZACAS-NEXT: andi a2, a0, 1
; RV64IA-NOZACAS-NEXT: sw a2, 0(a1)
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: atomicrmw_nand_i32_monotonic_crossbb:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: andi a1, a1, 1
; RV64IA-ZACAS-NEXT: beqz a1, .LBB57_4
; RV64IA-ZACAS-NEXT: # %bb.1: # %then
; RV64IA-ZACAS-NEXT: lw a1, 0(a0)
; RV64IA-ZACAS-NEXT: .LBB57_2: # %atomicrmw.start
; RV64IA-ZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV64IA-ZACAS-NEXT: mv a2, a1
; RV64IA-ZACAS-NEXT: not a3, a1
; RV64IA-ZACAS-NEXT: ori a3, a3, -2
; RV64IA-ZACAS-NEXT: amocas.w a1, a3, (a0)
; RV64IA-ZACAS-NEXT: bne a1, a2, .LBB57_2
; RV64IA-ZACAS-NEXT: # %bb.3: # %merge
; RV64IA-ZACAS-NEXT: mv a0, a1
; RV64IA-ZACAS-NEXT: ret
; RV64IA-ZACAS-NEXT: .LBB57_4: # %else
; RV64IA-ZACAS-NEXT: lw a1, 0(a0)
; RV64IA-ZACAS-NEXT: andi a2, a1, 1
; RV64IA-ZACAS-NEXT: sw a2, 0(a0)
; RV64IA-ZACAS-NEXT: mv a0, a1
; RV64IA-ZACAS-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw nand ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = and i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_or_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_or_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB58_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_or_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB58_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: ori a2, a1, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_or_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB58_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amoor.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB58_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: ori a2, a0, 1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_or_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB58_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_or_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB58_2: # %else
; RV64I-NEXT: lw a1, 0(a0)
; RV64I-NEXT: ori a2, a1, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_or_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB58_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amoor.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB58_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: ori a2, a0, 1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw or ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = or i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_xor_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_xor_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: beqz a1, .LBB59_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: li a1, 1
; RV32I-NEXT: li a2, 0
; RV32I-NEXT: call __atomic_fetch_xor_4
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB59_2: # %else
; RV32I-NEXT: lw a1, 0(a0)
; RV32I-NEXT: xori a2, a1, 1
; RV32I-NEXT: sw a2, 0(a0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_xor_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB59_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amoxor.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB59_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: xori a2, a0, 1
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_xor_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: beqz a1, .LBB59_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: li a2, 0
; RV64I-NEXT: call __atomic_fetch_xor_4
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB59_2: # %else
; RV64I-NEXT: lw a1, 0(a0)
; RV64I-NEXT: xori a2, a1, 1
; RV64I-NEXT: sw a2, 0(a0)
; RV64I-NEXT: sext.w a0, a1
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_xor_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB59_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amoxor.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB59_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: xori a2, a0, 1
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw xor ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = xor i32 %2, 1
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
define signext i32 @atomicrmw_max_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_max_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: beqz a1, .LBB60_5
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: j .LBB60_3
; RV32I-NEXT: .LBB60_2: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB60_3 Depth=1
; RV32I-NEXT: sw a1, 4(sp)
; RV32I-NEXT: addi a1, sp, 4
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a1, 4(sp)
; RV32I-NEXT: bnez a0, .LBB60_8
; RV32I-NEXT: .LBB60_3: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a1
; RV32I-NEXT: bgtz a1, .LBB60_2
; RV32I-NEXT: # %bb.4: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB60_3 Depth=1
; RV32I-NEXT: li a2, 1
; RV32I-NEXT: j .LBB60_2
; RV32I-NEXT: .LBB60_5: # %else
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: bgtz a1, .LBB60_7
; RV32I-NEXT: # %bb.6: # %else
; RV32I-NEXT: li a0, 1
; RV32I-NEXT: .LBB60_7: # %else
; RV32I-NEXT: sw a0, 0(s0)
; RV32I-NEXT: .LBB60_8: # %merge
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_max_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a1, 1
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: beqz a2, .LBB60_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a0, 1
; RV32IA-NEXT: amomax.w a0, a0, (a1)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB60_2: # %else
; RV32IA-NEXT: lw a0, 0(a1)
; RV32IA-NEXT: mv a2, a0
; RV32IA-NEXT: bgtz a0, .LBB60_4
; RV32IA-NEXT: # %bb.3: # %else
; RV32IA-NEXT: li a2, 1
; RV32IA-NEXT: .LBB60_4: # %else
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_max_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: beqz a1, .LBB60_5
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: j .LBB60_3
; RV64I-NEXT: .LBB60_2: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB60_3 Depth=1
; RV64I-NEXT: sw a1, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a1, 12(sp)
; RV64I-NEXT: bnez a0, .LBB60_8
; RV64I-NEXT: .LBB60_3: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: blt a0, a1, .LBB60_2
; RV64I-NEXT: # %bb.4: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB60_3 Depth=1
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: j .LBB60_2
; RV64I-NEXT: .LBB60_5: # %else
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: bgtz a1, .LBB60_7
; RV64I-NEXT: # %bb.6: # %else
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: .LBB60_7: # %else
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: .LBB60_8: # %merge
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_max_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a1, 1
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: beqz a2, .LBB60_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a0, 1
; RV64IA-NEXT: amomax.w a0, a0, (a1)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB60_2: # %else
; RV64IA-NEXT: lw a0, 0(a1)
; RV64IA-NEXT: mv a2, a0
; RV64IA-NEXT: bgtz a0, .LBB60_4
; RV64IA-NEXT: # %bb.3: # %else
; RV64IA-NEXT: li a2, 1
; RV64IA-NEXT: .LBB60_4: # %else
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw max ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = call i32 @llvm.smax.i32(i32 %2, i32 1)
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
declare i32 @llvm.smax.i32(i32, i32)
define signext i32 @atomicrmw_min_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_min_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: beqz a1, .LBB61_5
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: li s1, 2
; RV32I-NEXT: j .LBB61_3
; RV32I-NEXT: .LBB61_2: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB61_3 Depth=1
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a1, 0(sp)
; RV32I-NEXT: bnez a0, .LBB61_8
; RV32I-NEXT: .LBB61_3: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a1
; RV32I-NEXT: blt a1, s1, .LBB61_2
; RV32I-NEXT: # %bb.4: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB61_3 Depth=1
; RV32I-NEXT: li a2, 1
; RV32I-NEXT: j .LBB61_2
; RV32I-NEXT: .LBB61_5: # %else
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: blez a1, .LBB61_7
; RV32I-NEXT: # %bb.6: # %else
; RV32I-NEXT: li a0, 1
; RV32I-NEXT: .LBB61_7: # %else
; RV32I-NEXT: sw a0, 0(s0)
; RV32I-NEXT: .LBB61_8: # %merge
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_min_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a1, 1
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: beqz a2, .LBB61_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a0, 1
; RV32IA-NEXT: amomin.w a0, a0, (a1)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB61_2: # %else
; RV32IA-NEXT: lw a0, 0(a1)
; RV32IA-NEXT: mv a2, a0
; RV32IA-NEXT: blez a0, .LBB61_4
; RV32IA-NEXT: # %bb.3: # %else
; RV32IA-NEXT: li a2, 1
; RV32IA-NEXT: .LBB61_4: # %else
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_min_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: beqz a1, .LBB61_5
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: li s1, 2
; RV64I-NEXT: j .LBB61_3
; RV64I-NEXT: .LBB61_2: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB61_3 Depth=1
; RV64I-NEXT: sw a1, 4(sp)
; RV64I-NEXT: addi a1, sp, 4
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a1, 4(sp)
; RV64I-NEXT: bnez a0, .LBB61_8
; RV64I-NEXT: .LBB61_3: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: blt a1, s1, .LBB61_2
; RV64I-NEXT: # %bb.4: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB61_3 Depth=1
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: j .LBB61_2
; RV64I-NEXT: .LBB61_5: # %else
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: blez a1, .LBB61_7
; RV64I-NEXT: # %bb.6: # %else
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: .LBB61_7: # %else
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: .LBB61_8: # %merge
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_min_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a1, 1
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: beqz a2, .LBB61_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a0, 1
; RV64IA-NEXT: amomin.w a0, a0, (a1)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB61_2: # %else
; RV64IA-NEXT: lw a0, 0(a1)
; RV64IA-NEXT: mv a2, a0
; RV64IA-NEXT: blez a0, .LBB61_4
; RV64IA-NEXT: # %bb.3: # %else
; RV64IA-NEXT: li a2, 1
; RV64IA-NEXT: .LBB61_4: # %else
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw min ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = call i32 @llvm.smin.i32(i32 %2, i32 1)
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
declare i32 @llvm.smin.i32(i32, i32)
define signext i32 @atomicrmw_umax_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_umax_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: beqz a1, .LBB62_3
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: .LBB62_2: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: seqz a2, a1
; RV32I-NEXT: add a2, a1, a2
; RV32I-NEXT: sw a1, 4(sp)
; RV32I-NEXT: addi a1, sp, 4
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a1, 4(sp)
; RV32I-NEXT: beqz a0, .LBB62_2
; RV32I-NEXT: j .LBB62_4
; RV32I-NEXT: .LBB62_3: # %else
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: seqz a0, a1
; RV32I-NEXT: add a0, a1, a0
; RV32I-NEXT: sw a0, 0(s0)
; RV32I-NEXT: .LBB62_4: # %merge
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umax_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a1, a1, 1
; RV32IA-NEXT: beqz a1, .LBB62_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a1, 1
; RV32IA-NEXT: amomaxu.w a0, a1, (a0)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB62_2: # %else
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: lw a0, 0(a0)
; RV32IA-NEXT: seqz a2, a0
; RV32IA-NEXT: add a2, a0, a2
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umax_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: beqz a1, .LBB62_5
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: j .LBB62_3
; RV64I-NEXT: .LBB62_2: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB62_3 Depth=1
; RV64I-NEXT: sw a1, 12(sp)
; RV64I-NEXT: addi a1, sp, 12
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a1, 12(sp)
; RV64I-NEXT: bnez a0, .LBB62_6
; RV64I-NEXT: .LBB62_3: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: bltu a0, a1, .LBB62_2
; RV64I-NEXT: # %bb.4: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB62_3 Depth=1
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: j .LBB62_2
; RV64I-NEXT: .LBB62_5: # %else
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: seqz a0, a1
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: .LBB62_6: # %merge
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umax_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a1, a1, 1
; RV64IA-NEXT: beqz a1, .LBB62_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a1, 1
; RV64IA-NEXT: amomaxu.w a0, a1, (a0)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB62_2: # %else
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: lw a0, 0(a0)
; RV64IA-NEXT: seqz a2, a0
; RV64IA-NEXT: add a2, a0, a2
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw umax ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = call i32 @llvm.umax.i32(i32 %2, i32 1)
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
declare i32 @llvm.umax.i32(i32, i32)
define signext i32 @atomicrmw_umin_i32_monotonic_crossbb(ptr %a, i1 %c) nounwind {
; RV32I-LABEL: atomicrmw_umin_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
; RV32I-NEXT: andi a1, a1, 1
; RV32I-NEXT: mv s0, a0
; RV32I-NEXT: beqz a1, .LBB63_5
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: li s1, 2
; RV32I-NEXT: j .LBB63_3
; RV32I-NEXT: .LBB63_2: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB63_3 Depth=1
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a0, s0
; RV32I-NEXT: li a3, 0
; RV32I-NEXT: li a4, 0
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a1, 0(sp)
; RV32I-NEXT: bnez a0, .LBB63_8
; RV32I-NEXT: .LBB63_3: # %atomicrmw.start
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
; RV32I-NEXT: mv a2, a1
; RV32I-NEXT: bltu a1, s1, .LBB63_2
; RV32I-NEXT: # %bb.4: # %atomicrmw.start
; RV32I-NEXT: # in Loop: Header=BB63_3 Depth=1
; RV32I-NEXT: li a2, 1
; RV32I-NEXT: j .LBB63_2
; RV32I-NEXT: .LBB63_5: # %else
; RV32I-NEXT: lw a1, 0(s0)
; RV32I-NEXT: li a2, 1
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: bltu a1, a2, .LBB63_7
; RV32I-NEXT: # %bb.6: # %else
; RV32I-NEXT: li a0, 1
; RV32I-NEXT: .LBB63_7: # %else
; RV32I-NEXT: sw a0, 0(s0)
; RV32I-NEXT: .LBB63_8: # %merge
; RV32I-NEXT: mv a0, a1
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_umin_i32_monotonic_crossbb:
; RV32IA: # %bb.0:
; RV32IA-NEXT: andi a2, a1, 1
; RV32IA-NEXT: mv a1, a0
; RV32IA-NEXT: beqz a2, .LBB63_2
; RV32IA-NEXT: # %bb.1: # %then
; RV32IA-NEXT: li a0, 1
; RV32IA-NEXT: amominu.w a0, a0, (a1)
; RV32IA-NEXT: ret
; RV32IA-NEXT: .LBB63_2: # %else
; RV32IA-NEXT: lw a0, 0(a1)
; RV32IA-NEXT: li a3, 1
; RV32IA-NEXT: mv a2, a0
; RV32IA-NEXT: bltu a0, a3, .LBB63_4
; RV32IA-NEXT: # %bb.3: # %else
; RV32IA-NEXT: li a2, 1
; RV32IA-NEXT: .LBB63_4: # %else
; RV32IA-NEXT: sw a2, 0(a1)
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_umin_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -32
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: andi a1, a1, 1
; RV64I-NEXT: mv s0, a0
; RV64I-NEXT: beqz a1, .LBB63_5
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: li s1, 2
; RV64I-NEXT: j .LBB63_3
; RV64I-NEXT: .LBB63_2: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB63_3 Depth=1
; RV64I-NEXT: sw a1, 4(sp)
; RV64I-NEXT: addi a1, sp, 4
; RV64I-NEXT: mv a0, s0
; RV64I-NEXT: li a3, 0
; RV64I-NEXT: li a4, 0
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a1, 4(sp)
; RV64I-NEXT: bnez a0, .LBB63_8
; RV64I-NEXT: .LBB63_3: # %atomicrmw.start
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
; RV64I-NEXT: mv a2, a1
; RV64I-NEXT: bltu a1, s1, .LBB63_2
; RV64I-NEXT: # %bb.4: # %atomicrmw.start
; RV64I-NEXT: # in Loop: Header=BB63_3 Depth=1
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: j .LBB63_2
; RV64I-NEXT: .LBB63_5: # %else
; RV64I-NEXT: lw a1, 0(s0)
; RV64I-NEXT: li a2, 1
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: bltu a1, a2, .LBB63_7
; RV64I-NEXT: # %bb.6: # %else
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: .LBB63_7: # %else
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: .LBB63_8: # %merge
; RV64I-NEXT: mv a0, a1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_umin_i32_monotonic_crossbb:
; RV64IA: # %bb.0:
; RV64IA-NEXT: andi a2, a1, 1
; RV64IA-NEXT: mv a1, a0
; RV64IA-NEXT: beqz a2, .LBB63_2
; RV64IA-NEXT: # %bb.1: # %then
; RV64IA-NEXT: li a0, 1
; RV64IA-NEXT: amominu.w a0, a0, (a1)
; RV64IA-NEXT: ret
; RV64IA-NEXT: .LBB63_2: # %else
; RV64IA-NEXT: lw a0, 0(a1)
; RV64IA-NEXT: li a3, 1
; RV64IA-NEXT: mv a2, a0
; RV64IA-NEXT: bltu a0, a3, .LBB63_4
; RV64IA-NEXT: # %bb.3: # %else
; RV64IA-NEXT: li a2, 1
; RV64IA-NEXT: .LBB63_4: # %else
; RV64IA-NEXT: sw a2, 0(a1)
; RV64IA-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = atomicrmw umin ptr %a, i32 1 monotonic
br label %merge
else:
%2 = load i32, ptr %a, align 4
%3 = call i32 @llvm.umin.i32(i32 %2, i32 1)
store i32 %3, ptr %a
br label %merge
merge:
%4 = phi i32 [ %1, %then ], [ %2, %else ]
ret i32 %4
}
declare i32 @llvm.umin.i32(i32, i32)
define signext i32 @cmpxchg_i32_monotonic_crossbb(ptr %ptr, i32 signext %cmp, i32 signext %val, i1 zeroext %c) nounwind {
; RV32I-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV32I: # %bb.0:
; RV32I-NEXT: beqz a3, .LBB64_2
; RV32I-NEXT: # %bb.1: # %then
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: li a3, 5
; RV32I-NEXT: li a4, 5
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw a0, 8(sp)
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
; RV32I-NEXT: .LBB64_2: # %else
; RV32I-NEXT: lw a0, 0(a0)
; RV32I-NEXT: ret
;
; RV32IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV32IA-NOZACAS: # %bb.0:
; RV32IA-NOZACAS-NEXT: mv a4, a0
; RV32IA-NOZACAS-NEXT: beqz a3, .LBB64_2
; RV32IA-NOZACAS-NEXT: # %bb.1: # %then
; RV32IA-NOZACAS-NEXT: .LBB64_3: # %then
; RV32IA-NOZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV32IA-NOZACAS-NEXT: lr.w.aqrl a0, (a4)
; RV32IA-NOZACAS-NEXT: bne a0, a1, .LBB64_5
; RV32IA-NOZACAS-NEXT: # %bb.4: # %then
; RV32IA-NOZACAS-NEXT: # in Loop: Header=BB64_3 Depth=1
; RV32IA-NOZACAS-NEXT: sc.w.rl a3, a2, (a4)
; RV32IA-NOZACAS-NEXT: bnez a3, .LBB64_3
; RV32IA-NOZACAS-NEXT: .LBB64_5: # %then
; RV32IA-NOZACAS-NEXT: ret
; RV32IA-NOZACAS-NEXT: .LBB64_2: # %else
; RV32IA-NOZACAS-NEXT: lw a0, 0(a4)
; RV32IA-NOZACAS-NEXT: ret
;
; RV32IA-ZACAS-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV32IA-ZACAS: # %bb.0:
; RV32IA-ZACAS-NEXT: beqz a3, .LBB64_2
; RV32IA-ZACAS-NEXT: # %bb.1: # %then
; RV32IA-ZACAS-NEXT: fence rw, rw
; RV32IA-ZACAS-NEXT: amocas.w.aqrl a1, a2, (a0)
; RV32IA-ZACAS-NEXT: mv a0, a1
; RV32IA-ZACAS-NEXT: ret
; RV32IA-ZACAS-NEXT: .LBB64_2: # %else
; RV32IA-ZACAS-NEXT: lw a0, 0(a0)
; RV32IA-ZACAS-NEXT: ret
;
; RV64I-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV64I: # %bb.0:
; RV64I-NEXT: beqz a3, .LBB64_2
; RV64I-NEXT: # %bb.1: # %then
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sw a1, 4(sp)
; RV64I-NEXT: addi a1, sp, 4
; RV64I-NEXT: li a3, 5
; RV64I-NEXT: li a4, 5
; RV64I-NEXT: call __atomic_compare_exchange_4
; RV64I-NEXT: lw a0, 4(sp)
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB64_2: # %else
; RV64I-NEXT: lw a0, 0(a0)
; RV64I-NEXT: ret
;
; RV64IA-NOZACAS-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV64IA-NOZACAS: # %bb.0:
; RV64IA-NOZACAS-NEXT: beqz a3, .LBB64_2
; RV64IA-NOZACAS-NEXT: # %bb.1: # %then
; RV64IA-NOZACAS-NEXT: .LBB64_3: # %then
; RV64IA-NOZACAS-NEXT: # =>This Inner Loop Header: Depth=1
; RV64IA-NOZACAS-NEXT: lr.w.aqrl a3, (a0)
; RV64IA-NOZACAS-NEXT: bne a3, a1, .LBB64_5
; RV64IA-NOZACAS-NEXT: # %bb.4: # %then
; RV64IA-NOZACAS-NEXT: # in Loop: Header=BB64_3 Depth=1
; RV64IA-NOZACAS-NEXT: sc.w.rl a4, a2, (a0)
; RV64IA-NOZACAS-NEXT: bnez a4, .LBB64_3
; RV64IA-NOZACAS-NEXT: .LBB64_5: # %then
; RV64IA-NOZACAS-NEXT: sext.w a0, a3
; RV64IA-NOZACAS-NEXT: ret
; RV64IA-NOZACAS-NEXT: .LBB64_2: # %else
; RV64IA-NOZACAS-NEXT: lw a3, 0(a0)
; RV64IA-NOZACAS-NEXT: sext.w a0, a3
; RV64IA-NOZACAS-NEXT: ret
;
; RV64IA-ZACAS-LABEL: cmpxchg_i32_monotonic_crossbb:
; RV64IA-ZACAS: # %bb.0:
; RV64IA-ZACAS-NEXT: beqz a3, .LBB64_2
; RV64IA-ZACAS-NEXT: # %bb.1: # %then
; RV64IA-ZACAS-NEXT: fence rw, rw
; RV64IA-ZACAS-NEXT: amocas.w.aqrl a1, a2, (a0)
; RV64IA-ZACAS-NEXT: mv a0, a1
; RV64IA-ZACAS-NEXT: ret
; RV64IA-ZACAS-NEXT: .LBB64_2: # %else
; RV64IA-ZACAS-NEXT: lw a0, 0(a0)
; RV64IA-ZACAS-NEXT: ret
br i1 %c, label %then, label %else
then:
%1 = cmpxchg ptr %ptr, i32 %cmp, i32 %val seq_cst seq_cst
%2 = extractvalue { i32, i1 } %1, 0
br label %merge
else:
%3 = load i32, ptr %ptr, align 4
br label %merge
merge:
%4 = phi i32 [ %2, %then ], [ %3, %else ]
ret i32 %4
}