
After the refactoring in #149710 the logic change is trivial. Motivation for preferring sign-extended 32-bit loads (LW) vs zero-extended (LWU): * LW is compressible while LWU is not. * Helps to minimise the diff vs RV32 (e.g. LWU vs LW) * Helps to minimise distracting diffs vs GCC. I see this come up frequently when comparing GCC code and in these cases it's a red herring. Similar normalisation could be done for LHU and LH, but this is less well motivated as there is a compressed LHU (and if performing the change in RISCVOptWInstrs it wouldn't be done for RV32). There is a compressed LBU but not LB, meaning doing a similar normalisation for byte-sized loads would actually be a regression in terms of code size. Load narrowing when allowed by hasAllNBitUsers isn't explored in this patch. This changes ~20500 instructions in an RVA22 build of the llvm-test-suite including SPEC 2017. As part of the review, the option of doing the change at ISel time was explored but was found to be less effective.
5638 lines
187 KiB
LLVM
5638 lines
187 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,+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,+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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; RV32IA-NEXT: not a3, a3
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; RV64IA-NEXT: not a3, a3
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: zext.b a1, a1
|
|
; 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: zext.b a1, a1
|
|
; 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: zext.b a1, a1
|
|
; 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: zext.b a1, a1
|
|
; 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: li a3, 255
|
|
; RV32IA-NEXT: slli a1, a1, 24
|
|
; RV32IA-NEXT: andi a4, a0, 24
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; RV32IA-NEXT: srai a1, a1, 24
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; RV32IA-NEXT: xori a4, a4, 24
|
|
; RV32IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1
|
|
; RV32IA-NEXT: lr.w a5, (a2)
|
|
; RV32IA-NEXT: and a7, a5, a3
|
|
; RV32IA-NEXT: mv a6, a5
|
|
; RV32IA-NEXT: sll a7, a7, a4
|
|
; RV32IA-NEXT: sra a7, a7, a4
|
|
; 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, a3
|
|
; 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: li a3, 255
|
|
; RV64IA-NEXT: slli a1, a1, 56
|
|
; RV64IA-NEXT: andi a4, a0, 24
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; RV64IA-NEXT: srai a1, a1, 56
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; RV64IA-NEXT: xori a4, a4, 56
|
|
; RV64IA-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1
|
|
; RV64IA-NEXT: lr.w a5, (a2)
|
|
; RV64IA-NEXT: and a7, a5, a3
|
|
; RV64IA-NEXT: mv a6, a5
|
|
; RV64IA-NEXT: sll a7, a7, a4
|
|
; RV64IA-NEXT: sra a7, a7, a4
|
|
; 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, a3
|
|
; 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: li a3, 255
|
|
; RV32IA-NEXT: slli a1, a1, 24
|
|
; RV32IA-NEXT: andi a4, a0, 24
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; RV32IA-NEXT: srai a1, a1, 24
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; RV32IA-NEXT: xori a4, a4, 24
|
|
; RV32IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1
|
|
; RV32IA-NEXT: lr.w a5, (a2)
|
|
; RV32IA-NEXT: and a7, a5, a3
|
|
; RV32IA-NEXT: mv a6, a5
|
|
; RV32IA-NEXT: sll a7, a7, a4
|
|
; RV32IA-NEXT: sra a7, a7, a4
|
|
; 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, a3
|
|
; 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: li a3, 255
|
|
; RV64IA-NEXT: slli a1, a1, 56
|
|
; RV64IA-NEXT: andi a4, a0, 24
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; RV64IA-NEXT: srai a1, a1, 56
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; RV64IA-NEXT: xori a4, a4, 56
|
|
; RV64IA-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1
|
|
; RV64IA-NEXT: lr.w a5, (a2)
|
|
; RV64IA-NEXT: and a7, a5, a3
|
|
; RV64IA-NEXT: mv a6, a5
|
|
; RV64IA-NEXT: sll a7, a7, a4
|
|
; RV64IA-NEXT: sra a7, a7, a4
|
|
; 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, a3
|
|
; 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: zext.b s2, a1
|
|
; 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: zext.b a0, a3
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b s2, a1
|
|
; 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: zext.b a0, a3
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: zext.b s2, a1
|
|
; 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: zext.b a0, a3
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; 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: zext.b s2, a1
|
|
; 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: zext.b a0, a3
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; 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: and a1, a1, a3
|
|
; RV32IA-NEXT: not a3, a4
|
|
; 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, 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: and a1, a1, a3
|
|
; RV64IA-NEXT: not a3, a4
|
|
; 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, 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: lui a3, 16
|
|
; RV32IA-NEXT: slli a1, a1, 16
|
|
; RV32IA-NEXT: li a4, 16
|
|
; RV32IA-NEXT: andi a5, a0, 24
|
|
; RV32IA-NEXT: addi a3, a3, -1
|
|
; RV32IA-NEXT: srai a1, a1, 16
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; RV32IA-NEXT: sub a4, a4, a5
|
|
; RV32IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1
|
|
; RV32IA-NEXT: lr.w a5, (a2)
|
|
; RV32IA-NEXT: and a7, a5, a3
|
|
; RV32IA-NEXT: mv a6, a5
|
|
; RV32IA-NEXT: sll a7, a7, a4
|
|
; RV32IA-NEXT: sra a7, a7, a4
|
|
; RV32IA-NEXT: bge a7, a1, .LBB21_3
|
|
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1
|
|
; RV32IA-NEXT: xor a6, a5, a1
|
|
; RV32IA-NEXT: and a6, a6, a3
|
|
; RV32IA-NEXT: xor a6, a5, 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, a5, 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: lui a3, 16
|
|
; RV64IA-NEXT: slli a1, a1, 48
|
|
; RV64IA-NEXT: li a4, 48
|
|
; RV64IA-NEXT: andi a5, a0, 24
|
|
; RV64IA-NEXT: addi a3, a3, -1
|
|
; RV64IA-NEXT: srai a1, a1, 48
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; RV64IA-NEXT: sub a4, a4, a5
|
|
; RV64IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1
|
|
; RV64IA-NEXT: lr.w a5, (a2)
|
|
; RV64IA-NEXT: and a7, a5, a3
|
|
; RV64IA-NEXT: mv a6, a5
|
|
; RV64IA-NEXT: sll a7, a7, a4
|
|
; RV64IA-NEXT: sra a7, a7, a4
|
|
; RV64IA-NEXT: bge a7, a1, .LBB21_3
|
|
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1
|
|
; RV64IA-NEXT: xor a6, a5, a1
|
|
; RV64IA-NEXT: and a6, a6, a3
|
|
; RV64IA-NEXT: xor a6, a5, 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, a5, 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: lui a3, 16
|
|
; RV32IA-NEXT: slli a1, a1, 16
|
|
; RV32IA-NEXT: li a4, 16
|
|
; RV32IA-NEXT: andi a5, a0, 24
|
|
; RV32IA-NEXT: addi a3, a3, -1
|
|
; RV32IA-NEXT: srai a1, a1, 16
|
|
; RV32IA-NEXT: sll a3, a3, a0
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; RV32IA-NEXT: sub a4, a4, a5
|
|
; RV32IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1
|
|
; RV32IA-NEXT: lr.w a5, (a2)
|
|
; RV32IA-NEXT: and a7, a5, a3
|
|
; RV32IA-NEXT: mv a6, a5
|
|
; RV32IA-NEXT: sll a7, a7, a4
|
|
; RV32IA-NEXT: sra a7, a7, a4
|
|
; RV32IA-NEXT: bge a1, a7, .LBB22_3
|
|
; RV32IA-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1
|
|
; RV32IA-NEXT: xor a6, a5, a1
|
|
; RV32IA-NEXT: and a6, a6, a3
|
|
; RV32IA-NEXT: xor a6, a5, 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, a5, 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: lui a3, 16
|
|
; RV64IA-NEXT: slli a1, a1, 48
|
|
; RV64IA-NEXT: li a4, 48
|
|
; RV64IA-NEXT: andi a5, a0, 24
|
|
; RV64IA-NEXT: addi a3, a3, -1
|
|
; RV64IA-NEXT: srai a1, a1, 48
|
|
; RV64IA-NEXT: sllw a3, a3, a0
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; RV64IA-NEXT: sub a4, a4, a5
|
|
; RV64IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1
|
|
; RV64IA-NEXT: lr.w a5, (a2)
|
|
; RV64IA-NEXT: and a7, a5, a3
|
|
; RV64IA-NEXT: mv a6, a5
|
|
; RV64IA-NEXT: sll a7, a7, a4
|
|
; RV64IA-NEXT: sra a7, a7, a4
|
|
; RV64IA-NEXT: bge a1, a7, .LBB22_3
|
|
; RV64IA-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1
|
|
; RV64IA-NEXT: xor a6, a5, a1
|
|
; RV64IA-NEXT: and a6, a6, a3
|
|
; RV64IA-NEXT: xor a6, a5, 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, a5, 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: addi 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: addi 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, a2
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lw a4, 0(a0)
|
|
; RV32I-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32I-NEXT: li a4, 0
|
|
; RV32I-NEXT: li a5, 0
|
|
; RV32I-NEXT: call __atomic_compare_exchange_8
|
|
; RV32I-NEXT: lw a4, 8(sp)
|
|
; RV32I-NEXT: lw a5, 12(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, s0, .LBB43_4
|
|
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32I-NEXT: # in Loop: Header=BB43_2 Depth=1
|
|
; RV32I-NEXT: slt a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32IA-NEXT: mv s1, a0
|
|
; RV32IA-NEXT: lw a4, 0(a0)
|
|
; RV32IA-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32IA-NEXT: li a4, 0
|
|
; RV32IA-NEXT: li a5, 0
|
|
; RV32IA-NEXT: call __atomic_compare_exchange_8
|
|
; RV32IA-NEXT: lw a4, 8(sp)
|
|
; RV32IA-NEXT: lw a5, 12(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, s0, .LBB43_4
|
|
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32IA-NEXT: # in Loop: Header=BB43_2 Depth=1
|
|
; RV32IA-NEXT: slt a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lw a4, 0(a0)
|
|
; RV32I-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32I-NEXT: li a4, 0
|
|
; RV32I-NEXT: li a5, 0
|
|
; RV32I-NEXT: call __atomic_compare_exchange_8
|
|
; RV32I-NEXT: lw a4, 8(sp)
|
|
; RV32I-NEXT: lw a5, 12(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, s0, .LBB44_4
|
|
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32I-NEXT: # in Loop: Header=BB44_2 Depth=1
|
|
; RV32I-NEXT: slt a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32IA-NEXT: mv s1, a0
|
|
; RV32IA-NEXT: lw a4, 0(a0)
|
|
; RV32IA-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32IA-NEXT: li a4, 0
|
|
; RV32IA-NEXT: li a5, 0
|
|
; RV32IA-NEXT: call __atomic_compare_exchange_8
|
|
; RV32IA-NEXT: lw a4, 8(sp)
|
|
; RV32IA-NEXT: lw a5, 12(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, s0, .LBB44_4
|
|
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32IA-NEXT: # in Loop: Header=BB44_2 Depth=1
|
|
; RV32IA-NEXT: slt a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lw a4, 0(a0)
|
|
; RV32I-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32I-NEXT: li a4, 0
|
|
; RV32I-NEXT: li a5, 0
|
|
; RV32I-NEXT: call __atomic_compare_exchange_8
|
|
; RV32I-NEXT: lw a4, 8(sp)
|
|
; RV32I-NEXT: lw a5, 12(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, s0, .LBB45_4
|
|
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32I-NEXT: # in Loop: Header=BB45_2 Depth=1
|
|
; RV32I-NEXT: sltu a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32IA-NEXT: mv s1, a0
|
|
; RV32IA-NEXT: lw a4, 0(a0)
|
|
; RV32IA-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32IA-NEXT: li a4, 0
|
|
; RV32IA-NEXT: li a5, 0
|
|
; RV32IA-NEXT: call __atomic_compare_exchange_8
|
|
; RV32IA-NEXT: lw a4, 8(sp)
|
|
; RV32IA-NEXT: lw a5, 12(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, s0, .LBB45_4
|
|
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32IA-NEXT: # in Loop: Header=BB45_2 Depth=1
|
|
; RV32IA-NEXT: sltu a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: lw a4, 0(a0)
|
|
; RV32I-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32I-NEXT: li a4, 0
|
|
; RV32I-NEXT: li a5, 0
|
|
; RV32I-NEXT: call __atomic_compare_exchange_8
|
|
; RV32I-NEXT: lw a4, 8(sp)
|
|
; RV32I-NEXT: lw a5, 12(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, s0, .LBB46_4
|
|
; RV32I-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32I-NEXT: # in Loop: Header=BB46_2 Depth=1
|
|
; RV32I-NEXT: sltu a0, s0, 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, s0
|
|
; 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, a2
|
|
; RV32IA-NEXT: mv s1, a0
|
|
; RV32IA-NEXT: lw a4, 0(a0)
|
|
; RV32IA-NEXT: lw a5, 4(a0)
|
|
; 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, s1
|
|
; RV32IA-NEXT: li a4, 0
|
|
; RV32IA-NEXT: li a5, 0
|
|
; RV32IA-NEXT: call __atomic_compare_exchange_8
|
|
; RV32IA-NEXT: lw a4, 8(sp)
|
|
; RV32IA-NEXT: lw a5, 12(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, s0, .LBB46_4
|
|
; RV32IA-NEXT: # %bb.3: # %atomicrmw.start
|
|
; RV32IA-NEXT: # in Loop: Header=BB46_2 Depth=1
|
|
; RV32IA-NEXT: sltu a0, s0, 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, s0
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: zext.b a2, a2
|
|
; RV32IA-NEXT: sll a4, a4, a0
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: zext.b a2, a2
|
|
; RV64IA-NEXT: sllw a4, a4, a0
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; 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: zext.b a1, a1
|
|
; RV32IA-NEXT: zext.b a2, a2
|
|
; RV32IA-NEXT: sll a4, a4, a0
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; 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: zext.b a1, a1
|
|
; RV64IA-NEXT: zext.b a2, a2
|
|
; RV64IA-NEXT: sllw a4, a4, a0
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; 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: and a2, a2, a4
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; 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: and a2, a2, a4
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; 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: and a2, a2, a4
|
|
; RV32IA-NEXT: sll a1, a1, a0
|
|
; 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: and a2, a2, a4
|
|
; RV64IA-NEXT: sllw a1, a1, a0
|
|
; 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: lw 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: lw 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
|
|
}
|