diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index 44a148940ec96..1761b356b6558 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -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 diff --git a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-rcpc_immo.ll b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-rcpc_immo.ll index c80b18d178883..de12866fc2f4b 100644 --- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-rcpc_immo.ll +++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-rcpc_immo.ll @@ -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 @@ -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 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-store-fp16.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-store-fp16.ll new file mode 100644 index 0000000000000..6156b2587df68 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-store-fp16.ll @@ -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 +}