[X86] Cast atomic vectors in IR to support floats (#148899)
This commit casts floats to ints in an atomic load during AtomicExpand
to support
floating point types. It also is required to support 128 bit vectors in
SSE/AVX.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f4529dd..3be7d35 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -32956,6 +32956,13 @@
}
}
+TargetLowering::AtomicExpansionKind
+X86TargetLowering::shouldCastAtomicLoadInIR(LoadInst *LI) const {
+ if (LI->getType()->getScalarType()->isFloatingPointTy())
+ return AtomicExpansionKind::CastToInteger;
+ return AtomicExpansionKind::None;
+}
+
LoadInst *
X86TargetLowering::lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *AI) const {
unsigned NativeWidth = Subtarget.is64Bit() ? 64 : 32;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 0d05c57..9a95852 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -892,6 +892,8 @@
shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
TargetLoweringBase::AtomicExpansionKind
shouldExpandLogicAtomicRMWInIR(const AtomicRMWInst *AI) const;
+ TargetLoweringBase::AtomicExpansionKind
+ shouldCastAtomicLoadInIR(LoadInst *LI) const override;
void emitBitTestAtomicRMWIntrinsic(AtomicRMWInst *AI) const override;
void emitCmpArithAtomicRMWIntrinsic(AtomicRMWInst *AI) const override;
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 48291cd..6ab6f87 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1227,6 +1227,21 @@
def : Pat<(v2i64 (scalar_to_vector (i64 (atomic_load_64 addr:$src)))),
(VMOV64toPQIZrm addr:$src)>, Requires<[HasAVX512]>;
+// load atomic <2 x i64>
+def : Pat<(v2i64 (atomic_load_128_v2i64 addr:$src)),
+ (MOVAPDrm addr:$src)>, Requires<[UseSSE2]>;
+def : Pat<(v2i64 (atomic_load_128_v2i64 addr:$src)),
+ (VMOVAPDrm addr:$src)>, Requires<[UseAVX]>;
+def : Pat<(v2i64 (atomic_load_128_v2i64 addr:$src)),
+ (VMOVAPDZ128rm addr:$src)>, Requires<[HasAVX512]>;
+// load atomic <4 x i32>
+def : Pat<(v4i32 (atomic_load_128_v4i32 addr:$src)),
+ (MOVAPDrm addr:$src)>, Requires<[UseSSE2]>;
+def : Pat<(v4i32 (atomic_load_128_v4i32 addr:$src)),
+ (VMOVAPDrm addr:$src)>, Requires<[UseAVX]>;
+def : Pat<(v4i32 (atomic_load_128_v4i32 addr:$src)),
+ (VMOVAPDZ128rm addr:$src)>, Requires<[HasAVX512]>;
+
// Floating point loads/stores.
def : Pat<(atomic_store_32 (i32 (bitconvert (f32 FR32:$src))), addr:$dst),
(MOVSSmr addr:$dst, FR32:$src)>, Requires<[UseSSE1]>;
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 407a29e..00310f6 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -119,13 +119,13 @@
; CHECK-SSE-O3-LABEL: atomic_vec1_bfloat:
; CHECK-SSE-O3: # %bb.0:
; CHECK-SSE-O3-NEXT: movzwl (%rdi), %eax
-; CHECK-SSE-O3-NEXT: pinsrw $0, %eax, %xmm0
+; CHECK-SSE-O3-NEXT: movd %eax, %xmm0
; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec1_bfloat:
; CHECK-AVX-O3: # %bb.0:
; CHECK-AVX-O3-NEXT: movzwl (%rdi), %eax
-; CHECK-AVX-O3-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0
+; CHECK-AVX-O3-NEXT: vmovd %eax, %xmm0
; CHECK-AVX-O3-NEXT: retq
;
; CHECK-SSE-O0-LABEL: atomic_vec1_bfloat:
@@ -133,8 +133,7 @@
; CHECK-SSE-O0-NEXT: movw (%rdi), %cx
; CHECK-SSE-O0-NEXT: # implicit-def: $eax
; CHECK-SSE-O0-NEXT: movw %cx, %ax
-; CHECK-SSE-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE-O0-NEXT: pinsrw $0, %eax, %xmm0
+; CHECK-SSE-O0-NEXT: movd %eax, %xmm0
; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec1_bfloat:
@@ -142,8 +141,7 @@
; CHECK-AVX-O0-NEXT: movw (%rdi), %cx
; CHECK-AVX-O0-NEXT: # implicit-def: $eax
; CHECK-AVX-O0-NEXT: movw %cx, %ax
-; CHECK-AVX-O0-NEXT: # implicit-def: $xmm0
-; CHECK-AVX-O0-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0
+; CHECK-AVX-O0-NEXT: vmovd %eax, %xmm0
; CHECK-AVX-O0-NEXT: retq
%ret = load atomic <1 x bfloat>, ptr %x acquire, align 2
ret <1 x bfloat> %ret
@@ -298,11 +296,7 @@
define <2 x half> @atomic_vec2_half(ptr %x) {
; CHECK-SSE-O3-LABEL: atomic_vec2_half:
; CHECK-SSE-O3: # %bb.0:
-; CHECK-SSE-O3-NEXT: movl (%rdi), %eax
-; CHECK-SSE-O3-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE-O3-NEXT: shrl $16, %eax
-; CHECK-SSE-O3-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
+; CHECK-SSE-O3-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec2_half:
@@ -312,20 +306,7 @@
;
; CHECK-SSE-O0-LABEL: atomic_vec2_half:
; CHECK-SSE-O0: # %bb.0:
-; CHECK-SSE-O0-NEXT: movl (%rdi), %eax
-; CHECK-SSE-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE-O0-NEXT: movw %cx, %dx
-; CHECK-SSE-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE-O0-NEXT: movw %dx, %cx
-; CHECK-SSE-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE-O0-NEXT: pinsrw $0, %ecx, %xmm1
-; 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: # implicit-def: $xmm0
-; CHECK-SSE-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
+; CHECK-SSE-O0-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec2_half:
@@ -338,50 +319,22 @@
define <2 x bfloat> @atomic_vec2_bfloat(ptr %x) {
; CHECK-SSE-O3-LABEL: atomic_vec2_bfloat:
; CHECK-SSE-O3: # %bb.0:
-; CHECK-SSE-O3-NEXT: movl (%rdi), %eax
-; CHECK-SSE-O3-NEXT: movl %eax, %ecx
-; CHECK-SSE-O3-NEXT: shrl $16, %eax
-; CHECK-SSE-O3-NEXT: pinsrw $0, %ecx, %xmm0
-; CHECK-SSE-O3-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
+; CHECK-SSE-O3-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec2_bfloat:
; CHECK-AVX-O3: # %bb.0:
-; CHECK-AVX-O3-NEXT: movl (%rdi), %eax
-; CHECK-AVX-O3-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: shrl $16, %eax
-; CHECK-AVX-O3-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
+; CHECK-AVX-O3-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-AVX-O3-NEXT: retq
;
; CHECK-SSE-O0-LABEL: atomic_vec2_bfloat:
; CHECK-SSE-O0: # %bb.0:
-; CHECK-SSE-O0-NEXT: movl (%rdi), %eax
-; CHECK-SSE-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE-O0-NEXT: # kill: def $cx killed $cx killed $ecx
-; CHECK-SSE-O0-NEXT: movw %ax, %dx
-; CHECK-SSE-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE-O0-NEXT: movw %dx, %ax
-; CHECK-SSE-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE-O0-NEXT: movw %cx, %ax
-; CHECK-SSE-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE-O0-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
+; CHECK-SSE-O0-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec2_bfloat:
; CHECK-AVX-O0: # %bb.0:
-; CHECK-AVX-O0-NEXT: movl (%rdi), %eax
-; CHECK-AVX-O0-NEXT: movw %ax, %cx
-; CHECK-AVX-O0-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: shrl $16, %eax
-; CHECK-AVX-O0-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-AVX-O0-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
+; CHECK-AVX-O0-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-AVX-O0-NEXT: retq
%ret = load atomic <2 x bfloat>, ptr %x acquire, align 4
ret <2 x bfloat> %ret
@@ -418,13 +371,13 @@
; CHECK-SSE-O3-LABEL: atomic_vec1_half:
; CHECK-SSE-O3: # %bb.0:
; CHECK-SSE-O3-NEXT: movzwl (%rdi), %eax
-; CHECK-SSE-O3-NEXT: pinsrw $0, %eax, %xmm0
+; CHECK-SSE-O3-NEXT: movd %eax, %xmm0
; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec1_half:
; CHECK-AVX-O3: # %bb.0:
; CHECK-AVX-O3-NEXT: movzwl (%rdi), %eax
-; CHECK-AVX-O3-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0
+; CHECK-AVX-O3-NEXT: vmovd %eax, %xmm0
; CHECK-AVX-O3-NEXT: retq
;
; CHECK-SSE-O0-LABEL: atomic_vec1_half:
@@ -432,8 +385,7 @@
; CHECK-SSE-O0-NEXT: movw (%rdi), %cx
; CHECK-SSE-O0-NEXT: # implicit-def: $eax
; CHECK-SSE-O0-NEXT: movw %cx, %ax
-; CHECK-SSE-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE-O0-NEXT: pinsrw $0, %eax, %xmm0
+; CHECK-SSE-O0-NEXT: movd %eax, %xmm0
; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec1_half:
@@ -441,8 +393,7 @@
; CHECK-AVX-O0-NEXT: movw (%rdi), %cx
; CHECK-AVX-O0-NEXT: # implicit-def: $eax
; CHECK-AVX-O0-NEXT: movw %cx, %ax
-; CHECK-AVX-O0-NEXT: # implicit-def: $xmm0
-; CHECK-AVX-O0-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0
+; CHECK-AVX-O0-NEXT: vmovd %eax, %xmm0
; CHECK-AVX-O0-NEXT: retq
%ret = load atomic <1 x half>, ptr %x acquire, align 2
ret <1 x half> %ret
@@ -677,110 +628,20 @@
}
define <4 x half> @atomic_vec4_half(ptr %x) nounwind {
-; CHECK-SSE2-O3-LABEL: atomic_vec4_half:
-; CHECK-SSE2-O3: # %bb.0:
-; CHECK-SSE2-O3-NEXT: movq (%rdi), %rax
-; CHECK-SSE2-O3-NEXT: movl %eax, %ecx
-; CHECK-SSE2-O3-NEXT: shrl $16, %ecx
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %ecx, %xmm1
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE2-O3-NEXT: movq %rax, %rcx
-; CHECK-SSE2-O3-NEXT: shrq $32, %rcx
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %ecx, %xmm2
-; CHECK-SSE2-O3-NEXT: shrq $48, %rax
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %eax, %xmm3
-; CHECK-SSE2-O3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1],xmm2[2],xmm3[2],xmm2[3],xmm3[3]
-; CHECK-SSE2-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
-; CHECK-SSE2-O3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
-; CHECK-SSE2-O3-NEXT: retq
-;
-; CHECK-SSE4-O3-LABEL: atomic_vec4_half:
-; CHECK-SSE4-O3: # %bb.0:
-; CHECK-SSE4-O3-NEXT: movq (%rdi), %rax
-; CHECK-SSE4-O3-NEXT: movl %eax, %ecx
-; CHECK-SSE4-O3-NEXT: shrl $16, %ecx
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %ecx, %xmm1
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE4-O3-NEXT: movq %rax, %rcx
-; CHECK-SSE4-O3-NEXT: shrq $32, %rcx
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %ecx, %xmm2
-; CHECK-SSE4-O3-NEXT: shrq $48, %rax
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %eax, %xmm3
-; CHECK-SSE4-O3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1],xmm2[2],xmm3[2],xmm2[3],xmm3[3]
-; CHECK-SSE4-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
-; CHECK-SSE4-O3-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm2[0],zero,zero
-; CHECK-SSE4-O3-NEXT: retq
+; CHECK-SSE-O3-LABEL: atomic_vec4_half:
+; CHECK-SSE-O3: # %bb.0:
+; CHECK-SSE-O3-NEXT: movq (%rdi), %xmm0
+; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec4_half:
; CHECK-AVX-O3: # %bb.0:
; CHECK-AVX-O3-NEXT: vmovq (%rdi), %xmm0
; CHECK-AVX-O3-NEXT: retq
;
-; CHECK-SSE2-O0-LABEL: atomic_vec4_half:
-; CHECK-SSE2-O0: # %bb.0:
-; CHECK-SSE2-O0-NEXT: movq (%rdi), %rax
-; CHECK-SSE2-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE2-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE2-O0-NEXT: movw %cx, %dx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE2-O0-NEXT: movw %dx, %cx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm2
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %ecx, %xmm2
-; CHECK-SSE2-O0-NEXT: movw %ax, %dx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE2-O0-NEXT: movw %dx, %cx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %ecx, %xmm0
-; CHECK-SSE2-O0-NEXT: movq %rax, %rcx
-; CHECK-SSE2-O0-NEXT: shrq $32, %rcx
-; CHECK-SSE2-O0-NEXT: movw %cx, %dx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE2-O0-NEXT: movw %dx, %cx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %ecx, %xmm1
-; CHECK-SSE2-O0-NEXT: shrq $48, %rax
-; CHECK-SSE2-O0-NEXT: movw %ax, %cx
-; CHECK-SSE2-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE2-O0-NEXT: movw %cx, %ax
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm3
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %eax, %xmm3
-; CHECK-SSE2-O0-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3]
-; CHECK-SSE2-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
-; CHECK-SSE2-O0-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; CHECK-SSE2-O0-NEXT: retq
-;
-; CHECK-SSE4-O0-LABEL: atomic_vec4_half:
-; CHECK-SSE4-O0: # %bb.0:
-; CHECK-SSE4-O0-NEXT: movq (%rdi), %rax
-; CHECK-SSE4-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE4-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE4-O0-NEXT: movw %cx, %dx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE4-O0-NEXT: movw %dx, %cx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm2
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %ecx, %xmm2
-; CHECK-SSE4-O0-NEXT: movw %ax, %dx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE4-O0-NEXT: movw %dx, %cx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %ecx, %xmm0
-; CHECK-SSE4-O0-NEXT: movq %rax, %rcx
-; CHECK-SSE4-O0-NEXT: shrq $32, %rcx
-; CHECK-SSE4-O0-NEXT: movw %cx, %dx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $ecx
-; CHECK-SSE4-O0-NEXT: movw %dx, %cx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %ecx, %xmm1
-; CHECK-SSE4-O0-NEXT: shrq $48, %rax
-; CHECK-SSE4-O0-NEXT: movw %ax, %cx
-; CHECK-SSE4-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE4-O0-NEXT: movw %cx, %ax
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm3
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %eax, %xmm3
-; CHECK-SSE4-O0-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3]
-; CHECK-SSE4-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
-; CHECK-SSE4-O0-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],zero,zero
-; CHECK-SSE4-O0-NEXT: retq
+; CHECK-SSE-O0-LABEL: atomic_vec4_half:
+; CHECK-SSE-O0: # %bb.0:
+; CHECK-SSE-O0-NEXT: movq (%rdi), %xmm0
+; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec4_half:
; CHECK-AVX-O0: # %bb.0:
@@ -790,141 +651,24 @@
ret <4 x half> %ret
}
define <4 x bfloat> @atomic_vec4_bfloat(ptr %x) nounwind {
-; CHECK-SSE2-O3-LABEL: atomic_vec4_bfloat:
-; CHECK-SSE2-O3: # %bb.0:
-; CHECK-SSE2-O3-NEXT: movq (%rdi), %rax
-; CHECK-SSE2-O3-NEXT: movl %eax, %ecx
-; CHECK-SSE2-O3-NEXT: shrl $16, %ecx
-; CHECK-SSE2-O3-NEXT: movq %rax, %rdx
-; CHECK-SSE2-O3-NEXT: shrq $32, %rdx
-; CHECK-SSE2-O3-NEXT: movl %eax, %esi
-; CHECK-SSE2-O3-NEXT: shrq $48, %rax
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %edx, %xmm2
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %esi, %xmm0
-; CHECK-SSE2-O3-NEXT: pinsrw $0, %ecx, %xmm3
-; CHECK-SSE2-O3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-SSE2-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
-; CHECK-SSE2-O3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
-; CHECK-SSE2-O3-NEXT: retq
-;
-; CHECK-SSE4-O3-LABEL: atomic_vec4_bfloat:
-; CHECK-SSE4-O3: # %bb.0:
-; CHECK-SSE4-O3-NEXT: movq (%rdi), %rax
-; CHECK-SSE4-O3-NEXT: movl %eax, %ecx
-; CHECK-SSE4-O3-NEXT: shrl $16, %ecx
-; CHECK-SSE4-O3-NEXT: movq %rax, %rdx
-; CHECK-SSE4-O3-NEXT: shrq $32, %rdx
-; CHECK-SSE4-O3-NEXT: movl %eax, %esi
-; CHECK-SSE4-O3-NEXT: shrq $48, %rax
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %edx, %xmm2
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %esi, %xmm0
-; CHECK-SSE4-O3-NEXT: pinsrw $0, %ecx, %xmm3
-; CHECK-SSE4-O3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-SSE4-O3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
-; CHECK-SSE4-O3-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm2[0],zero,zero
-; CHECK-SSE4-O3-NEXT: retq
+; CHECK-SSE-O3-LABEL: atomic_vec4_bfloat:
+; CHECK-SSE-O3: # %bb.0:
+; CHECK-SSE-O3-NEXT: movq (%rdi), %xmm0
+; CHECK-SSE-O3-NEXT: retq
;
; CHECK-AVX-O3-LABEL: atomic_vec4_bfloat:
; CHECK-AVX-O3: # %bb.0:
-; CHECK-AVX-O3-NEXT: movq (%rdi), %rax
-; CHECK-AVX-O3-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: movq %rax, %rcx
-; CHECK-AVX-O3-NEXT: shrq $48, %rcx
-; CHECK-AVX-O3-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: movq %rax, %rcx
-; CHECK-AVX-O3-NEXT: shrq $32, %rcx
-; CHECK-AVX-O3-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: shrl $16, %eax
-; CHECK-AVX-O3-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O3-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
+; CHECK-AVX-O3-NEXT: vmovq (%rdi), %xmm0
; CHECK-AVX-O3-NEXT: retq
;
-; CHECK-SSE2-O0-LABEL: atomic_vec4_bfloat:
-; CHECK-SSE2-O0: # %bb.0:
-; CHECK-SSE2-O0-NEXT: movq (%rdi), %rax
-; CHECK-SSE2-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE2-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE2-O0-NEXT: # kill: def $cx killed $cx killed $ecx
-; CHECK-SSE2-O0-NEXT: movw %ax, %dx
-; CHECK-SSE2-O0-NEXT: movq %rax, %rsi
-; CHECK-SSE2-O0-NEXT: shrq $32, %rsi
-; CHECK-SSE2-O0-NEXT: # kill: def $si killed $si killed $rsi
-; CHECK-SSE2-O0-NEXT: shrq $48, %rax
-; CHECK-SSE2-O0-NEXT: movw %ax, %di
-; CHECK-SSE2-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE2-O0-NEXT: movw %di, %ax
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE2-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE2-O0-NEXT: movw %si, %ax
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE2-O0-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
-; CHECK-SSE2-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE2-O0-NEXT: movw %dx, %ax
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE2-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE2-O0-NEXT: movw %cx, %ax
-; CHECK-SSE2-O0-NEXT: # implicit-def: $xmm2
-; CHECK-SSE2-O0-NEXT: pinsrw $0, %eax, %xmm2
-; CHECK-SSE2-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
-; CHECK-SSE2-O0-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; CHECK-SSE2-O0-NEXT: retq
-;
-; CHECK-SSE4-O0-LABEL: atomic_vec4_bfloat:
-; CHECK-SSE4-O0: # %bb.0:
-; CHECK-SSE4-O0-NEXT: movq (%rdi), %rax
-; CHECK-SSE4-O0-NEXT: movl %eax, %ecx
-; CHECK-SSE4-O0-NEXT: shrl $16, %ecx
-; CHECK-SSE4-O0-NEXT: # kill: def $cx killed $cx killed $ecx
-; CHECK-SSE4-O0-NEXT: movw %ax, %dx
-; CHECK-SSE4-O0-NEXT: movq %rax, %rsi
-; CHECK-SSE4-O0-NEXT: shrq $32, %rsi
-; CHECK-SSE4-O0-NEXT: # kill: def $si killed $si killed $rsi
-; CHECK-SSE4-O0-NEXT: shrq $48, %rax
-; CHECK-SSE4-O0-NEXT: movw %ax, %di
-; CHECK-SSE4-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE4-O0-NEXT: movw %di, %ax
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE4-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE4-O0-NEXT: movw %si, %ax
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm1
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %eax, %xmm1
-; CHECK-SSE4-O0-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
-; CHECK-SSE4-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE4-O0-NEXT: movw %dx, %ax
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm0
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %eax, %xmm0
-; CHECK-SSE4-O0-NEXT: # implicit-def: $eax
-; CHECK-SSE4-O0-NEXT: movw %cx, %ax
-; CHECK-SSE4-O0-NEXT: # implicit-def: $xmm2
-; CHECK-SSE4-O0-NEXT: pinsrw $0, %eax, %xmm2
-; CHECK-SSE4-O0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
-; CHECK-SSE4-O0-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],zero,zero
-; CHECK-SSE4-O0-NEXT: retq
+; CHECK-SSE-O0-LABEL: atomic_vec4_bfloat:
+; CHECK-SSE-O0: # %bb.0:
+; CHECK-SSE-O0-NEXT: movq (%rdi), %xmm0
+; CHECK-SSE-O0-NEXT: retq
;
; CHECK-AVX-O0-LABEL: atomic_vec4_bfloat:
; CHECK-AVX-O0: # %bb.0:
-; CHECK-AVX-O0-NEXT: movq (%rdi), %rax
-; CHECK-AVX-O0-NEXT: movq %rax, %rcx
-; CHECK-AVX-O0-NEXT: shrq $48, %rcx
-; CHECK-AVX-O0-NEXT: # kill: def $cx killed $cx killed $rcx
-; CHECK-AVX-O0-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: movq %rax, %rcx
-; CHECK-AVX-O0-NEXT: shrq $32, %rcx
-; CHECK-AVX-O0-NEXT: # kill: def $cx killed $cx killed $rcx
-; CHECK-AVX-O0-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: movw %ax, %cx
-; CHECK-AVX-O0-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: # kill: def $eax killed $eax killed $rax
-; CHECK-AVX-O0-NEXT: shrl $16, %eax
-; CHECK-AVX-O0-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-AVX-O0-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
-; CHECK-AVX-O0-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
+; CHECK-AVX-O0-NEXT: vmovq (%rdi), %xmm0
; CHECK-AVX-O0-NEXT: retq
%ret = load atomic <4 x bfloat>, ptr %x acquire, align 8
ret <4 x bfloat> %ret
@@ -982,6 +726,72 @@
ret <4 x float> %ret
}
+define <4 x float> @atomic_vec4_float_align(ptr %x) nounwind {
+;
+; CHECK-SSE2-O3-LABEL: atomic_vec4_float_align:
+; CHECK-SSE2-O3: # %bb.0:
+; CHECK-SSE2-O3-NEXT: pushq %rax
+; CHECK-SSE2-O3-NEXT: movl $2, %esi
+; CHECK-SSE2-O3-NEXT: callq __atomic_load_16@PLT
+; CHECK-SSE2-O3-NEXT: movq %rdx, %xmm1
+; CHECK-SSE2-O3-NEXT: movq %rax, %xmm0
+; CHECK-SSE2-O3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-SSE2-O3-NEXT: popq %rax
+; CHECK-SSE2-O3-NEXT: retq
+;
+; CHECK-SSE4-O3-LABEL: atomic_vec4_float_align:
+; CHECK-SSE4-O3: # %bb.0:
+; CHECK-SSE4-O3-NEXT: pushq %rbx
+; CHECK-SSE4-O3-NEXT: xorl %eax, %eax
+; CHECK-SSE4-O3-NEXT: xorl %edx, %edx
+; CHECK-SSE4-O3-NEXT: xorl %ecx, %ecx
+; CHECK-SSE4-O3-NEXT: xorl %ebx, %ebx
+; CHECK-SSE4-O3-NEXT: lock cmpxchg16b (%rdi)
+; CHECK-SSE4-O3-NEXT: movq %rdx, %xmm1
+; CHECK-SSE4-O3-NEXT: movq %rax, %xmm0
+; CHECK-SSE4-O3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-SSE4-O3-NEXT: popq %rbx
+; CHECK-SSE4-O3-NEXT: retq
+;
+; CHECK-AVX-O3-LABEL: atomic_vec4_float_align:
+; CHECK-AVX-O3: # %bb.0:
+; CHECK-AVX-O3-NEXT: vmovaps (%rdi), %xmm0
+; CHECK-AVX-O3-NEXT: retq
+;
+; CHECK-SSE2-O0-LABEL: atomic_vec4_float_align:
+; CHECK-SSE2-O0: # %bb.0:
+; CHECK-SSE2-O0-NEXT: pushq %rax
+; CHECK-SSE2-O0-NEXT: movl $2, %esi
+; CHECK-SSE2-O0-NEXT: callq __atomic_load_16@PLT
+; CHECK-SSE2-O0-NEXT: movq %rdx, %xmm1
+; CHECK-SSE2-O0-NEXT: movq %rax, %xmm0
+; CHECK-SSE2-O0-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-SSE2-O0-NEXT: popq %rax
+; CHECK-SSE2-O0-NEXT: retq
+;
+; CHECK-SSE4-O0-LABEL: atomic_vec4_float_align:
+; CHECK-SSE4-O0: # %bb.0:
+; CHECK-SSE4-O0-NEXT: pushq %rbx
+; CHECK-SSE4-O0-NEXT: xorl %eax, %eax
+; CHECK-SSE4-O0-NEXT: movl %eax, %ebx
+; CHECK-SSE4-O0-NEXT: movq %rbx, %rax
+; CHECK-SSE4-O0-NEXT: movq %rbx, %rdx
+; CHECK-SSE4-O0-NEXT: movq %rbx, %rcx
+; CHECK-SSE4-O0-NEXT: lock cmpxchg16b (%rdi)
+; CHECK-SSE4-O0-NEXT: movq %rdx, %xmm1
+; CHECK-SSE4-O0-NEXT: movq %rax, %xmm0
+; CHECK-SSE4-O0-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-SSE4-O0-NEXT: popq %rbx
+; CHECK-SSE4-O0-NEXT: retq
+;
+; CHECK-AVX-O0-LABEL: atomic_vec4_float_align:
+; CHECK-AVX-O0: # %bb.0:
+; CHECK-AVX-O0-NEXT: vmovaps (%rdi), %xmm0
+; CHECK-AVX-O0-NEXT: retq
+ %ret = load atomic <4 x float>, ptr %x acquire, align 16
+ ret <4 x float> %ret
+}
+
define <8 x double> @atomic_vec8_double(ptr %x) nounwind {
; CHECK-SSE-O3-LABEL: atomic_vec8_double:
; CHECK-SSE-O3: # %bb.0: