Skip to content
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,10 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
return Query.Types[0] == s128 &&
Query.MMODescrs[0].Ordering != AtomicOrdering::NotAtomic;
})
.widenScalarIf(
all(scalarNarrowerThan(0, 32),
atomicOrderingAtLeastOrStrongerThan(0, AtomicOrdering::Release)),
changeTo(0, s32))
.legalForTypesWithMemDesc(
{{s8, p0, s8, 8}, {s16, p0, s8, 8}, // truncstorei8 from s16
{s32, p0, s8, 8}, // truncstorei8 from s32
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,10 @@ define void @store_atomic_i128_unaligned_seq_cst(i128 %value, ptr %ptr) {
ret void
}

; TODO: missed opportunity to emit a stlurb w/ GISel
define void @store_atomic_i8_from_gep() {
; GISEL-LABEL: store_atomic_i8_from_gep:
; GISEL: bl init
; GISEL: add x9, x8, #1
; GISEL: stlrb w8, [x9]
; GISEL: stlurb w8, [x9, #1]
;
; SDAG-LABEL: store_atomic_i8_from_gep:
; SDAG: bl init
Expand All @@ -374,12 +372,10 @@ define void @store_atomic_i8_from_gep() {
ret void
}

; TODO: missed opportunity to emit a stlurh w/ GISel
define void @store_atomic_i16_from_gep() {
; GISEL-LABEL: store_atomic_i16_from_gep:
; GISEL: bl init
; GISEL: add x9, x8, #2
; GISEL: stlrh w8, [x9]
; GISEL: stlurh w8, [x9, #2]
;
; SDAG-LABEL: store_atomic_i16_from_gep:
; SDAG: bl init
Expand Down
44 changes: 44 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-store-fp16.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=arm64-apple-ios -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=CHECK-NOFP16
; RUN: llc < %s -mtriple=arm64-apple-ios -mattr=+fullfp16 -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=CHECK-FP16

; Test for https://github.com/llvm/llvm-project/issues/171494
; Atomic store of bitcast half to i16 was generating incorrect code (mrs instead of fmov).

define void @atomic_store_half(ptr %addr, half %val) {
; CHECK-NOFP16-LABEL: atomic_store_half:
; CHECK-NOFP16: ; %bb.0:
; CHECK-NOFP16-NEXT: ; kill: def $h0 killed $h0 def $s0
; CHECK-NOFP16-NEXT: fmov w8, s0
; CHECK-NOFP16-NEXT: stlrh w8, [x0]
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: atomic_store_half:
; CHECK-FP16: ; %bb.0:
; CHECK-FP16-NEXT: ; kill: def $h0 killed $h0 def $s0
; CHECK-FP16-NEXT: fmov w8, s0
; CHECK-FP16-NEXT: stlrh w8, [x0]
; CHECK-FP16-NEXT: ret
%ival = bitcast half %val to i16
store atomic i16 %ival, ptr %addr release, align 2
ret void
}

define void @atomic_store_bfloat(ptr %addr, bfloat %val) {
; CHECK-NOFP16-LABEL: atomic_store_bfloat:
; CHECK-NOFP16: ; %bb.0:
; CHECK-NOFP16-NEXT: ; kill: def $h0 killed $h0 def $s0
; CHECK-NOFP16-NEXT: fmov w8, s0
; CHECK-NOFP16-NEXT: stlrh w8, [x0]
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: atomic_store_bfloat:
; CHECK-FP16: ; %bb.0:
; CHECK-FP16-NEXT: ; kill: def $h0 killed $h0 def $s0
; CHECK-FP16-NEXT: fmov w8, s0
; CHECK-FP16-NEXT: stlrh w8, [x0]
; CHECK-FP16-NEXT: ret
%ival = bitcast bfloat %val to i16
store atomic i16 %ival, ptr %addr release, align 2
ret void
}