https://github.com/jofrn created https://github.com/llvm/llvm-project/pull/197166
When lowering atomic <1 x T> vector types with floats, selection can fail since this pattern is unsupported. To support this, floats can be casted to an integer type of the same size. Store-side counterpart to #148895. Stacked on top of #197165. >From 686ed50a3c21313ce133b2e316a7294b9cc04fa7 Mon Sep 17 00:00:00 2001 From: jofrn <[email protected]> Date: Tue, 12 May 2026 04:16:46 -0700 Subject: [PATCH] [X86] Manage atomic store of fp -> int promotion in DAG When lowering atomic <1 x T> vector types with floats, selection can fail since this pattern is unsupported. To support this, floats can be casted to an integer type of the same size. --- llvm/lib/Target/X86/X86ISelLowering.cpp | 4 + llvm/test/CodeGen/X86/atomic-load-store.ll | 134 +++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index aa5b864df5936..fea1caf0854f5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2753,6 +2753,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationPromotedToType(ISD::ATOMIC_LOAD, MVT::f32, MVT::i32); setOperationPromotedToType(ISD::ATOMIC_LOAD, MVT::f64, MVT::i64); + setOperationPromotedToType(ISD::ATOMIC_STORE, MVT::f16, MVT::i16); + setOperationPromotedToType(ISD::ATOMIC_STORE, MVT::f32, MVT::i32); + setOperationPromotedToType(ISD::ATOMIC_STORE, MVT::f64, MVT::i64); + // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine({ISD::VECTOR_SHUFFLE, ISD::SCALAR_TO_VECTOR, diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll b/llvm/test/CodeGen/X86/atomic-load-store.ll index 8e74276019e17..549015c37e2d0 100644 --- a/llvm/test/CodeGen/X86/atomic-load-store.ll +++ b/llvm/test/CodeGen/X86/atomic-load-store.ll @@ -222,6 +222,140 @@ define void @store_atomic_vec1_ptr(ptr %x, <1 x ptr> %v) nounwind { ret void } +define void @store_atomic_vec1_bfloat(ptr %x, <1 x bfloat> %v) { +; CHECK-SSE-O3-LABEL: store_atomic_vec1_bfloat: +; CHECK-SSE-O3: # %bb.0: +; CHECK-SSE-O3-NEXT: pextrw $0, %xmm0, %eax +; CHECK-SSE-O3-NEXT: movw %ax, (%rdi) +; CHECK-SSE-O3-NEXT: retq +; +; CHECK-AVX-O3-LABEL: store_atomic_vec1_bfloat: +; CHECK-AVX-O3: # %bb.0: +; CHECK-AVX-O3-NEXT: vpextrw $0, %xmm0, %eax +; CHECK-AVX-O3-NEXT: movw %ax, (%rdi) +; CHECK-AVX-O3-NEXT: retq +; +; CHECK-SSE-O0-LABEL: store_atomic_vec1_bfloat: +; CHECK-SSE-O0: # %bb.0: +; CHECK-SSE-O0-NEXT: pushq %rax +; CHECK-SSE-O0-NEXT: .cfi_def_cfa_offset 16 +; CHECK-SSE-O0-NEXT: movq %rdi, (%rsp) # 8-byte Spill +; CHECK-SSE-O0-NEXT: pextrw $0, %xmm0, %eax +; CHECK-SSE-O0-NEXT: movw %ax, %cx +; CHECK-SSE-O0-NEXT: # implicit-def: $eax +; CHECK-SSE-O0-NEXT: movw %cx, %ax +; CHECK-SSE-O0-NEXT: shll $16, %eax +; CHECK-SSE-O0-NEXT: movd %eax, %xmm0 +; CHECK-SSE-O0-NEXT: callq __truncsfbf2@PLT +; CHECK-SSE-O0-NEXT: movq (%rsp), %rdi # 8-byte Reload +; CHECK-SSE-O0-NEXT: pextrw $0, %xmm0, %eax +; CHECK-SSE-O0-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-SSE-O0-NEXT: movw %ax, (%rdi) +; CHECK-SSE-O0-NEXT: popq %rax +; CHECK-SSE-O0-NEXT: .cfi_def_cfa_offset 8 +; CHECK-SSE-O0-NEXT: retq +; +; CHECK-AVX-O0-LABEL: store_atomic_vec1_bfloat: +; CHECK-AVX-O0: # %bb.0: +; CHECK-AVX-O0-NEXT: pushq %rax +; CHECK-AVX-O0-NEXT: .cfi_def_cfa_offset 16 +; CHECK-AVX-O0-NEXT: movq %rdi, (%rsp) # 8-byte Spill +; CHECK-AVX-O0-NEXT: vpextrw $0, %xmm0, %eax +; CHECK-AVX-O0-NEXT: movw %ax, %cx +; CHECK-AVX-O0-NEXT: # implicit-def: $eax +; CHECK-AVX-O0-NEXT: movw %cx, %ax +; CHECK-AVX-O0-NEXT: shll $16, %eax +; CHECK-AVX-O0-NEXT: vmovd %eax, %xmm0 +; CHECK-AVX-O0-NEXT: callq __truncsfbf2@PLT +; CHECK-AVX-O0-NEXT: movq (%rsp), %rdi # 8-byte Reload +; CHECK-AVX-O0-NEXT: vpextrw $0, %xmm0, %eax +; CHECK-AVX-O0-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-AVX-O0-NEXT: movw %ax, (%rdi) +; CHECK-AVX-O0-NEXT: popq %rax +; CHECK-AVX-O0-NEXT: .cfi_def_cfa_offset 8 +; CHECK-AVX-O0-NEXT: retq + store atomic <1 x bfloat> %v, ptr %x release, align 2 + ret void +} + +define void @store_atomic_vec1_half(ptr %x, <1 x half> %v) { +; CHECK-SSE-O3-LABEL: store_atomic_vec1_half: +; CHECK-SSE-O3: # %bb.0: +; CHECK-SSE-O3-NEXT: pextrw $0, %xmm0, %eax +; CHECK-SSE-O3-NEXT: movw %ax, (%rdi) +; CHECK-SSE-O3-NEXT: retq +; +; CHECK-AVX-O3-LABEL: store_atomic_vec1_half: +; CHECK-AVX-O3: # %bb.0: +; CHECK-AVX-O3-NEXT: vpextrw $0, %xmm0, %eax +; CHECK-AVX-O3-NEXT: movw %ax, (%rdi) +; CHECK-AVX-O3-NEXT: retq +; +; CHECK-SSE-O0-LABEL: store_atomic_vec1_half: +; CHECK-SSE-O0: # %bb.0: +; CHECK-SSE-O0-NEXT: pextrw $0, %xmm0, %eax +; CHECK-SSE-O0-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-SSE-O0-NEXT: movw %ax, (%rdi) +; CHECK-SSE-O0-NEXT: retq +; +; CHECK-AVX-O0-LABEL: store_atomic_vec1_half: +; CHECK-AVX-O0: # %bb.0: +; CHECK-AVX-O0-NEXT: vpextrw $0, %xmm0, %eax +; CHECK-AVX-O0-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-AVX-O0-NEXT: movw %ax, (%rdi) +; CHECK-AVX-O0-NEXT: retq + store atomic <1 x half> %v, ptr %x release, align 2 + ret void +} + +define void @store_atomic_vec1_float(ptr %x, <1 x float> %v) { +; CHECK-SSE-O3-LABEL: store_atomic_vec1_float: +; CHECK-SSE-O3: # %bb.0: +; CHECK-SSE-O3-NEXT: movss %xmm0, (%rdi) +; CHECK-SSE-O3-NEXT: retq +; +; CHECK-AVX-O3-LABEL: store_atomic_vec1_float: +; CHECK-AVX-O3: # %bb.0: +; CHECK-AVX-O3-NEXT: vmovss %xmm0, (%rdi) +; CHECK-AVX-O3-NEXT: retq +; +; CHECK-SSE-O0-LABEL: store_atomic_vec1_float: +; CHECK-SSE-O0: # %bb.0: +; CHECK-SSE-O0-NEXT: movss %xmm0, (%rdi) +; CHECK-SSE-O0-NEXT: retq +; +; CHECK-AVX-O0-LABEL: store_atomic_vec1_float: +; CHECK-AVX-O0: # %bb.0: +; CHECK-AVX-O0-NEXT: vmovss %xmm0, (%rdi) +; CHECK-AVX-O0-NEXT: retq + store atomic <1 x float> %v, ptr %x release, align 4 + ret void +} + +define void @store_atomic_vec1_double_align(ptr %x, <1 x double> %v) nounwind { +; CHECK-SSE-O3-LABEL: store_atomic_vec1_double_align: +; CHECK-SSE-O3: # %bb.0: +; CHECK-SSE-O3-NEXT: movsd %xmm0, (%rdi) +; CHECK-SSE-O3-NEXT: retq +; +; CHECK-AVX-O3-LABEL: store_atomic_vec1_double_align: +; CHECK-AVX-O3: # %bb.0: +; CHECK-AVX-O3-NEXT: vmovsd %xmm0, (%rdi) +; CHECK-AVX-O3-NEXT: retq +; +; CHECK-SSE-O0-LABEL: store_atomic_vec1_double_align: +; CHECK-SSE-O0: # %bb.0: +; CHECK-SSE-O0-NEXT: movsd %xmm0, (%rdi) +; CHECK-SSE-O0-NEXT: retq +; +; CHECK-AVX-O0-LABEL: store_atomic_vec1_double_align: +; CHECK-AVX-O0: # %bb.0: +; CHECK-AVX-O0-NEXT: vmovsd %xmm0, (%rdi) +; CHECK-AVX-O0-NEXT: retq + store atomic <1 x double> %v, ptr %x release, align 8 + ret void +} + define <2 x i8> @atomic_vec2_i8(ptr %x) { ; CHECK-SSE-O3-LABEL: atomic_vec2_i8: ; CHECK-SSE-O3: # %bb.0: _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
