
If we're loading a constant value, print the constant (and the zero upper elements) instead of just the shuffle mask. This did require me to move the shuffle mask handling into addConstantComments as we can't handle this in the MC layer.
1288 lines
46 KiB
LLVM
1288 lines
46 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE41
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=AVX
|
|
;
|
|
; 32-bit SSE tests to make sure we do reasonable things.
|
|
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse | FileCheck %s --check-prefixes=X86-SSE,X86-SSE1
|
|
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=X86-SSE,X86-SSE41
|
|
|
|
define <2 x double> @merge_2f64_f64_23(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_2f64_f64_23:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 16(%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_2f64_f64_23:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 16(%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_2f64_f64_23:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: fldl 16(%eax)
|
|
; X86-SSE1-NEXT: fldl 24(%eax)
|
|
; X86-SSE1-NEXT: fxch %st(1)
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_2f64_f64_23:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 16(%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds double, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds double, ptr %ptr, i64 3
|
|
%val0 = load double, ptr %ptr0
|
|
%val1 = load double, ptr %ptr1
|
|
%res0 = insertelement <2 x double> undef, double %val0, i32 0
|
|
%res1 = insertelement <2 x double> %res0, double %val1, i32 1
|
|
ret <2 x double> %res1
|
|
}
|
|
|
|
define <2 x i64> @merge_2i64_i64_12(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_2i64_i64_12:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 8(%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_2i64_i64_12:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 8(%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_2i64_i64_12:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %esi
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %edi
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, 12(%eax)
|
|
; X86-SSE1-NEXT: movl %edi, 8(%eax)
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_2i64_i64_12:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 8(%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i64, ptr %ptr, i64 1
|
|
%ptr1 = getelementptr inbounds i64, ptr %ptr, i64 2
|
|
%val0 = load i64, ptr %ptr0
|
|
%val1 = load i64, ptr %ptr1
|
|
%res0 = insertelement <2 x i64> undef, i64 %val0, i32 0
|
|
%res1 = insertelement <2 x i64> %res0, i64 %val1, i32 1
|
|
ret <2 x i64> %res1
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_2345(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4f32_f32_2345:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 8(%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_2345:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 8(%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE-LABEL: merge_4f32_f32_2345:
|
|
; X86-SSE: # %bb.0:
|
|
; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE-NEXT: movups 8(%eax), %xmm0
|
|
; X86-SSE-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 3
|
|
%ptr2 = getelementptr inbounds float, ptr %ptr, i64 4
|
|
%ptr3 = getelementptr inbounds float, ptr %ptr, i64 5
|
|
%val0 = load float, ptr %ptr0
|
|
%val1 = load float, ptr %ptr1
|
|
%val2 = load float, ptr %ptr2
|
|
%val3 = load float, ptr %ptr3
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
%res2 = insertelement <4 x float> %res1, float %val2, i32 2
|
|
%res3 = insertelement <4 x float> %res2, float %val3, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_3zuu(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4f32_f32_3zuu:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_3zuu:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE-LABEL: merge_4f32_f32_3zuu:
|
|
; X86-SSE: # %bb.0:
|
|
; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 3
|
|
%val0 = load float, ptr %ptr0
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float 0.0, i32 1
|
|
ret <4 x float> %res1
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_34uu(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4f32_f32_34uu:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_34uu:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_34uu:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: xorps %xmm0, %xmm0
|
|
; X86-SSE1-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_34uu:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 3
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 4
|
|
%val0 = load float, ptr %ptr0
|
|
%val1 = load float, ptr %ptr1
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
ret <4 x float> %res1
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_34z6(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE2-LABEL: merge_4f32_f32_34z6:
|
|
; SSE2: # %bb.0:
|
|
; SSE2-NEXT: movups 12(%rdi), %xmm0
|
|
; SSE2-NEXT: xorps %xmm1, %xmm1
|
|
; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[3,0]
|
|
; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
|
|
; SSE2-NEXT: retq
|
|
;
|
|
; SSE41-LABEL: merge_4f32_f32_34z6:
|
|
; SSE41: # %bb.0:
|
|
; SSE41-NEXT: movups 12(%rdi), %xmm1
|
|
; SSE41-NEXT: xorps %xmm0, %xmm0
|
|
; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2],xmm1[3]
|
|
; SSE41-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_34z6:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0
|
|
; AVX-NEXT: vblendps {{.*#+}} xmm0 = mem[0,1],xmm0[2],mem[3]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_34z6:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movups 12(%eax), %xmm0
|
|
; X86-SSE1-NEXT: xorps %xmm1, %xmm1
|
|
; X86-SSE1-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[3,0]
|
|
; X86-SSE1-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_34z6:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 12(%eax), %xmm1
|
|
; X86-SSE41-NEXT: xorps %xmm0, %xmm0
|
|
; X86-SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2],xmm1[3]
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 3
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 4
|
|
%ptr3 = getelementptr inbounds float, ptr %ptr, i64 6
|
|
%val0 = load float, ptr %ptr0
|
|
%val1 = load float, ptr %ptr1
|
|
%val3 = load float, ptr %ptr3
|
|
%res0 = insertelement <4 x float> zeroinitializer, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
%res3 = insertelement <4 x float> %res1, float %val3, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_45zz(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4f32_f32_45zz:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_45zz:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_45zz:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: xorps %xmm0, %xmm0
|
|
; X86-SSE1-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_45zz:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 4
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 5
|
|
%val0 = load float, ptr %ptr0
|
|
%val1 = load float, ptr %ptr1
|
|
%res0 = insertelement <4 x float> zeroinitializer, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
ret <4 x float> %res1
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_012u(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE2-LABEL: merge_4f32_f32_012u:
|
|
; SSE2: # %bb.0:
|
|
; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; SSE2-NEXT: retq
|
|
;
|
|
; SSE41-LABEL: merge_4f32_f32_012u:
|
|
; SSE41: # %bb.0:
|
|
; SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; SSE41-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_012u:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_012u:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: xorps %xmm0, %xmm0
|
|
; X86-SSE1-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; X86-SSE1-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_012u:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 1
|
|
%ptr2 = getelementptr inbounds float, ptr %ptr, i64 2
|
|
%val0 = load float, ptr %ptr
|
|
%val1 = load float, ptr %ptr1
|
|
%val2 = load float, ptr %ptr2
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
%res2 = insertelement <4 x float> %res1, float %val2, i32 2
|
|
%res3 = insertelement <4 x float> %res2, float undef, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_019u(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE2-LABEL: merge_4f32_f32_019u:
|
|
; SSE2: # %bb.0:
|
|
; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; SSE2-NEXT: retq
|
|
;
|
|
; SSE41-LABEL: merge_4f32_f32_019u:
|
|
; SSE41: # %bb.0:
|
|
; SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; SSE41-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_019u:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_019u:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: xorps %xmm0, %xmm0
|
|
; X86-SSE1-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; X86-SSE1-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_019u:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 1
|
|
%ptr2 = getelementptr inbounds float, ptr %ptr, i64 9
|
|
%val0 = load float, ptr %ptr
|
|
%val1 = load float, ptr %ptr1
|
|
%val2 = load float, ptr %ptr2
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
%res2 = insertelement <4 x float> %res1, float %val2, i32 2
|
|
%res3 = insertelement <4 x float> %res2, float undef, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_23u5(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_23u5:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 8(%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_23u5:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 8(%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_23u5:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %esi
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl %ecx, 12(%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_23u5:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 8(%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 3
|
|
%ptr3 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%val3 = load i32, ptr %ptr3
|
|
%res0 = insertelement <4 x i32> undef, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
%res3 = insertelement <4 x i32> %res1, i32 %val3, i32 3
|
|
ret <4 x i32> %res3
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_23u5_inc2(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_23u5_inc2:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 8(%rdi), %xmm0
|
|
; SSE-NEXT: incl 8(%rdi)
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_23u5_inc2:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 8(%rdi), %xmm0
|
|
; AVX-NEXT: incl 8(%rdi)
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_23u5_inc2:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %esi
|
|
; X86-SSE1-NEXT: leal 1(%edx), %edi
|
|
; X86-SSE1-NEXT: movl %edi, 8(%ecx)
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl %ecx, 12(%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_23u5_inc2:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 8(%eax), %xmm0
|
|
; X86-SSE41-NEXT: incl 8(%eax)
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 3
|
|
%ptr3 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%inc = add i32 %val0, 1
|
|
store i32 %inc, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%val3 = load i32, ptr %ptr3
|
|
%res0 = insertelement <4 x i32> undef, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
%res3 = insertelement <4 x i32> %res1, i32 %val3, i32 3
|
|
ret <4 x i32> %res3
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_23u5_inc3(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_23u5_inc3:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 8(%rdi), %xmm0
|
|
; SSE-NEXT: incl 12(%rdi)
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_23u5_inc3:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 8(%rdi), %xmm0
|
|
; AVX-NEXT: incl 12(%rdi)
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_23u5_inc3:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %esi
|
|
; X86-SSE1-NEXT: leal 1(%esi), %edi
|
|
; X86-SSE1-NEXT: movl %edi, 12(%ecx)
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl %ecx, 12(%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_23u5_inc3:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 8(%eax), %xmm0
|
|
; X86-SSE41-NEXT: incl 12(%eax)
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 3
|
|
%ptr3 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%inc = add i32 %val1, 1
|
|
store i32 %inc, ptr %ptr1
|
|
%val3 = load i32, ptr %ptr3
|
|
%res0 = insertelement <4 x i32> undef, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
%res3 = insertelement <4 x i32> %res1, i32 %val3, i32 3
|
|
ret <4 x i32> %res3
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_3zuu(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_3zuu:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_3zuu:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_3zuu:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 4(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_3zuu:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 3
|
|
%val0 = load i32, ptr %ptr0
|
|
%res0 = insertelement <4 x i32> undef, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 0, i32 1
|
|
ret <4 x i32> %res1
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_34uu(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_34uu:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_34uu:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_34uu:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_34uu:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 3
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 4
|
|
%val0 = load i32, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%res0 = insertelement <4 x i32> undef, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
ret <4 x i32> %res1
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_45zz(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_45zz:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_45zz:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_45zz:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 12(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 8(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_45zz:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 4
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%res0 = insertelement <4 x i32> zeroinitializer, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
ret <4 x i32> %res1
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_45zz_inc4(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_45zz_inc4:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: incl 16(%rdi)
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_45zz_inc4:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: incl 16(%rdi)
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_45zz_inc4:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %esi
|
|
; X86-SSE1-NEXT: leal 1(%edx), %edi
|
|
; X86-SSE1-NEXT: movl %edi, 16(%ecx)
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 12(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 8(%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_45zz_inc4:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: incl 16(%eax)
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 4
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%inc = add i32 %val0, 1
|
|
store i32 %inc, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%res0 = insertelement <4 x i32> zeroinitializer, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
ret <4 x i32> %res1
|
|
}
|
|
|
|
define <4 x i32> @merge_4i32_i32_45zz_inc5(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4i32_i32_45zz_inc5:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: incl 20(%rdi)
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_45zz_inc5:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: incl 20(%rdi)
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_45zz_inc5:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %esi
|
|
; X86-SSE1-NEXT: leal 1(%esi), %edi
|
|
; X86-SSE1-NEXT: movl %edi, 20(%ecx)
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 12(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 8(%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_45zz_inc5:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: incl 20(%eax)
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i32, ptr %ptr, i64 4
|
|
%ptr1 = getelementptr inbounds i32, ptr %ptr, i64 5
|
|
%val0 = load i32, ptr %ptr0
|
|
%val1 = load i32, ptr %ptr1
|
|
%inc = add i32 %val1, 1
|
|
store i32 %inc, ptr %ptr1
|
|
%res0 = insertelement <4 x i32> zeroinitializer, i32 %val0, i32 0
|
|
%res1 = insertelement <4 x i32> %res0, i32 %val1, i32 1
|
|
ret <4 x i32> %res1
|
|
}
|
|
|
|
define <8 x i16> @merge_8i16_i16_23u567u9(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_8i16_i16_23u567u9:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups 4(%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_8i16_i16_23u567u9:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups 4(%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_8i16_i16_23u567u9:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 4(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 10(%ecx), %esi
|
|
; X86-SSE1-NEXT: movzwl 14(%ecx), %edi
|
|
; X86-SSE1-NEXT: movzwl 18(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movw %di, 10(%eax)
|
|
; X86-SSE1-NEXT: movw %cx, 14(%eax)
|
|
; X86-SSE1-NEXT: movl %esi, 6(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_8i16_i16_23u567u9:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups 4(%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i16, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds i16, ptr %ptr, i64 3
|
|
%ptr3 = getelementptr inbounds i16, ptr %ptr, i64 5
|
|
%ptr4 = getelementptr inbounds i16, ptr %ptr, i64 6
|
|
%ptr5 = getelementptr inbounds i16, ptr %ptr, i64 7
|
|
%ptr7 = getelementptr inbounds i16, ptr %ptr, i64 9
|
|
%val0 = load i16, ptr %ptr0
|
|
%val1 = load i16, ptr %ptr1
|
|
%val3 = load i16, ptr %ptr3
|
|
%val4 = load i16, ptr %ptr4
|
|
%val5 = load i16, ptr %ptr5
|
|
%val7 = load i16, ptr %ptr7
|
|
%res0 = insertelement <8 x i16> undef, i16 %val0, i32 0
|
|
%res1 = insertelement <8 x i16> %res0, i16 %val1, i32 1
|
|
%res3 = insertelement <8 x i16> %res1, i16 %val3, i32 3
|
|
%res4 = insertelement <8 x i16> %res3, i16 %val4, i32 4
|
|
%res5 = insertelement <8 x i16> %res4, i16 %val5, i32 5
|
|
%res7 = insertelement <8 x i16> %res5, i16 %val7, i32 7
|
|
ret <8 x i16> %res7
|
|
}
|
|
|
|
define <8 x i16> @merge_8i16_i16_34uuuuuu(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_8i16_i16_34uuuuuu:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_8i16_i16_34uuuuuu:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_8i16_i16_34uuuuuu:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 6(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, (%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_8i16_i16_34uuuuuu:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i16, ptr %ptr, i64 3
|
|
%ptr1 = getelementptr inbounds i16, ptr %ptr, i64 4
|
|
%val0 = load i16, ptr %ptr0
|
|
%val1 = load i16, ptr %ptr1
|
|
%res0 = insertelement <8 x i16> undef, i16 %val0, i32 0
|
|
%res1 = insertelement <8 x i16> %res0, i16 %val1, i32 1
|
|
ret <8 x i16> %res1
|
|
}
|
|
|
|
define <8 x i16> @merge_8i16_i16_45u7zzzz(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_8i16_i16_45u7zzzz:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_8i16_i16_45u7zzzz:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_8i16_i16_45u7zzzz:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movzwl 14(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movw %cx, 6(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 12(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 8(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_8i16_i16_45u7zzzz:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i16, ptr %ptr, i64 4
|
|
%ptr1 = getelementptr inbounds i16, ptr %ptr, i64 5
|
|
%ptr3 = getelementptr inbounds i16, ptr %ptr, i64 7
|
|
%val0 = load i16, ptr %ptr0
|
|
%val1 = load i16, ptr %ptr1
|
|
%val3 = load i16, ptr %ptr3
|
|
%res0 = insertelement <8 x i16> undef, i16 %val0, i32 0
|
|
%res1 = insertelement <8 x i16> %res0, i16 %val1, i32 1
|
|
%res3 = insertelement <8 x i16> %res1, i16 %val3, i32 3
|
|
%res4 = insertelement <8 x i16> %res3, i16 0, i32 4
|
|
%res5 = insertelement <8 x i16> %res4, i16 0, i32 5
|
|
%res6 = insertelement <8 x i16> %res5, i16 0, i32 6
|
|
%res7 = insertelement <8 x i16> %res6, i16 0, i32 7
|
|
ret <8 x i16> %res7
|
|
}
|
|
|
|
define <16 x i8> @merge_16i8_i8_01u3456789ABCDuF(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_16i8_i8_01u3456789ABCDuF:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movups (%rdi), %xmm0
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_16i8_i8_01u3456789ABCDuF:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovups (%rdi), %xmm0
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_16i8_i8_01u3456789ABCDuF:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %ebp
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %ebx
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 16
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 20
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -20
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -16
|
|
; X86-SSE1-NEXT: .cfi_offset %ebx, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %ebp, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movzwl (%ecx), %ebp
|
|
; X86-SSE1-NEXT: movl 3(%ecx), %esi
|
|
; X86-SSE1-NEXT: movl 7(%ecx), %edi
|
|
; X86-SSE1-NEXT: movzwl 11(%ecx), %ebx
|
|
; X86-SSE1-NEXT: movzbl 13(%ecx), %edx
|
|
; X86-SSE1-NEXT: movzbl 15(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movb %dl, 13(%eax)
|
|
; X86-SSE1-NEXT: movb %cl, 15(%eax)
|
|
; X86-SSE1-NEXT: movw %bx, 11(%eax)
|
|
; X86-SSE1-NEXT: movl %edi, 7(%eax)
|
|
; X86-SSE1-NEXT: movl %esi, 3(%eax)
|
|
; X86-SSE1-NEXT: movw %bp, (%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 16
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: popl %ebx
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %ebp
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_16i8_i8_01u3456789ABCDuF:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movups (%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%ptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
%ptr4 = getelementptr inbounds i8, ptr %ptr, i64 4
|
|
%ptr5 = getelementptr inbounds i8, ptr %ptr, i64 5
|
|
%ptr6 = getelementptr inbounds i8, ptr %ptr, i64 6
|
|
%ptr7 = getelementptr inbounds i8, ptr %ptr, i64 7
|
|
%ptr8 = getelementptr inbounds i8, ptr %ptr, i64 8
|
|
%ptr9 = getelementptr inbounds i8, ptr %ptr, i64 9
|
|
%ptrA = getelementptr inbounds i8, ptr %ptr, i64 10
|
|
%ptrB = getelementptr inbounds i8, ptr %ptr, i64 11
|
|
%ptrC = getelementptr inbounds i8, ptr %ptr, i64 12
|
|
%ptrD = getelementptr inbounds i8, ptr %ptr, i64 13
|
|
%ptrF = getelementptr inbounds i8, ptr %ptr, i64 15
|
|
%val0 = load i8, ptr %ptr
|
|
%val1 = load i8, ptr %ptr1
|
|
%val3 = load i8, ptr %ptr3
|
|
%val4 = load i8, ptr %ptr4
|
|
%val5 = load i8, ptr %ptr5
|
|
%val6 = load i8, ptr %ptr6
|
|
%val7 = load i8, ptr %ptr7
|
|
%val8 = load i8, ptr %ptr8
|
|
%val9 = load i8, ptr %ptr9
|
|
%valA = load i8, ptr %ptrA
|
|
%valB = load i8, ptr %ptrB
|
|
%valC = load i8, ptr %ptrC
|
|
%valD = load i8, ptr %ptrD
|
|
%valF = load i8, ptr %ptrF
|
|
%res0 = insertelement <16 x i8> undef, i8 %val0, i32 0
|
|
%res1 = insertelement <16 x i8> %res0, i8 %val1, i32 1
|
|
%res3 = insertelement <16 x i8> %res1, i8 %val3, i32 3
|
|
%res4 = insertelement <16 x i8> %res3, i8 %val4, i32 4
|
|
%res5 = insertelement <16 x i8> %res4, i8 %val5, i32 5
|
|
%res6 = insertelement <16 x i8> %res5, i8 %val6, i32 6
|
|
%res7 = insertelement <16 x i8> %res6, i8 %val7, i32 7
|
|
%res8 = insertelement <16 x i8> %res7, i8 %val8, i32 8
|
|
%res9 = insertelement <16 x i8> %res8, i8 %val9, i32 9
|
|
%resA = insertelement <16 x i8> %res9, i8 %valA, i32 10
|
|
%resB = insertelement <16 x i8> %resA, i8 %valB, i32 11
|
|
%resC = insertelement <16 x i8> %resB, i8 %valC, i32 12
|
|
%resD = insertelement <16 x i8> %resC, i8 %valD, i32 13
|
|
%resF = insertelement <16 x i8> %resD, i8 %valF, i32 15
|
|
ret <16 x i8> %resF
|
|
}
|
|
|
|
define <16 x i8> @merge_16i8_i8_01u3uuzzuuuuuzzz(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_16i8_i8_01u3uuzzuuuuuzzz:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_16i8_i8_01u3uuzzuuuuuzzz:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_16i8_i8_01u3uuzzuuuuuzzz:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movzwl (%ecx), %edx
|
|
; X86-SSE1-NEXT: movzbl 3(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movb %cl, 3(%eax)
|
|
; X86-SSE1-NEXT: movw %dx, (%eax)
|
|
; X86-SSE1-NEXT: movb $0, 15(%eax)
|
|
; X86-SSE1-NEXT: movw $0, 13(%eax)
|
|
; X86-SSE1-NEXT: movw $0, 6(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_16i8_i8_01u3uuzzuuuuuzzz:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%ptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
%val0 = load i8, ptr %ptr
|
|
%val1 = load i8, ptr %ptr1
|
|
%val3 = load i8, ptr %ptr3
|
|
%res0 = insertelement <16 x i8> undef, i8 %val0, i32 0
|
|
%res1 = insertelement <16 x i8> %res0, i8 %val1, i32 1
|
|
%res3 = insertelement <16 x i8> %res1, i8 %val3, i32 3
|
|
%res6 = insertelement <16 x i8> %res3, i8 0, i32 6
|
|
%res7 = insertelement <16 x i8> %res6, i8 0, i32 7
|
|
%resD = insertelement <16 x i8> %res7, i8 0, i32 13
|
|
%resE = insertelement <16 x i8> %resD, i8 0, i32 14
|
|
%resF = insertelement <16 x i8> %resE, i8 0, i32 15
|
|
ret <16 x i8> %resF
|
|
}
|
|
|
|
define <16 x i8> @merge_16i8_i8_0123uu67uuuuuzzz(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_16i8_i8_0123uu67uuuuuzzz:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_16i8_i8_0123uu67uuuuuzzz:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_16i8_i8_0123uu67uuuuuzzz:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl (%ecx), %edx
|
|
; X86-SSE1-NEXT: movzwl 6(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movw %cx, 6(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: movb $0, 15(%eax)
|
|
; X86-SSE1-NEXT: movw $0, 13(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_16i8_i8_0123uu67uuuuuzzz:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%ptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
|
%ptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
%ptr6 = getelementptr inbounds i8, ptr %ptr, i64 6
|
|
%ptr7 = getelementptr inbounds i8, ptr %ptr, i64 7
|
|
%val0 = load i8, ptr %ptr
|
|
%val1 = load i8, ptr %ptr1
|
|
%val2 = load i8, ptr %ptr2
|
|
%val3 = load i8, ptr %ptr3
|
|
%val6 = load i8, ptr %ptr6
|
|
%val7 = load i8, ptr %ptr7
|
|
%res0 = insertelement <16 x i8> undef, i8 %val0, i32 0
|
|
%res1 = insertelement <16 x i8> %res0, i8 %val1, i32 1
|
|
%res2 = insertelement <16 x i8> %res1, i8 %val2, i32 2
|
|
%res3 = insertelement <16 x i8> %res2, i8 %val3, i32 3
|
|
%res6 = insertelement <16 x i8> %res3, i8 %val6, i32 6
|
|
%res7 = insertelement <16 x i8> %res6, i8 %val7, i32 7
|
|
%resD = insertelement <16 x i8> %res7, i8 0, i32 13
|
|
%resE = insertelement <16 x i8> %resD, i8 0, i32 14
|
|
%resF = insertelement <16 x i8> %resE, i8 0, i32 15
|
|
ret <16 x i8> %resF
|
|
}
|
|
|
|
define void @merge_4i32_i32_combine(ptr %dst, ptr %src) {
|
|
; SSE-LABEL: merge_4i32_i32_combine:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: movaps %xmm0, (%rdi)
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4i32_i32_combine:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: vmovaps %xmm0, (%rdi)
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4i32_i32_combine:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm1 = [NaN,0.0E+0,0.0E+0,0.0E+0]
|
|
; X86-SSE1-NEXT: andps %xmm0, %xmm1
|
|
; X86-SSE1-NEXT: movaps %xmm1, (%eax)
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4i32_i32_combine:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: movaps %xmm0, (%eax)
|
|
; X86-SSE41-NEXT: retl
|
|
%1 = load i32, ptr %src
|
|
%2 = insertelement <4 x i32> undef, i32 %1, i32 0
|
|
%3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> zeroinitializer
|
|
%4 = lshr <4 x i32> %3, <i32 0, i32 undef, i32 undef, i32 undef>
|
|
%5 = and <4 x i32> %4, <i32 -1, i32 0, i32 0, i32 0>
|
|
store <4 x i32> %5, ptr %dst
|
|
ret void
|
|
}
|
|
|
|
;
|
|
; consecutive loads including any/all volatiles may not be combined
|
|
;
|
|
|
|
define <2 x i64> @merge_2i64_i64_12_volatile(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_2i64_i64_12_volatile:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
|
|
; SSE-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
|
|
; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_2i64_i64_12_volatile:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero
|
|
; AVX-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero
|
|
; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_2i64_i64_12_volatile:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: pushl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: pushl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 12
|
|
; X86-SSE1-NEXT: .cfi_offset %esi, -12
|
|
; X86-SSE1-NEXT: .cfi_offset %edi, -8
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl 8(%ecx), %edx
|
|
; X86-SSE1-NEXT: movl 12(%ecx), %esi
|
|
; X86-SSE1-NEXT: movl 16(%ecx), %edi
|
|
; X86-SSE1-NEXT: movl 20(%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, 12(%eax)
|
|
; X86-SSE1-NEXT: movl %edi, 8(%eax)
|
|
; X86-SSE1-NEXT: movl %esi, 4(%eax)
|
|
; X86-SSE1-NEXT: movl %edx, (%eax)
|
|
; X86-SSE1-NEXT: popl %esi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 8
|
|
; X86-SSE1-NEXT: popl %edi
|
|
; X86-SSE1-NEXT: .cfi_def_cfa_offset 4
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: merge_2i64_i64_12_volatile:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: pinsrd $1, 12(%eax), %xmm0
|
|
; X86-SSE41-NEXT: pinsrd $2, 16(%eax), %xmm0
|
|
; X86-SSE41-NEXT: pinsrd $3, 20(%eax), %xmm0
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds i64, ptr %ptr, i64 1
|
|
%ptr1 = getelementptr inbounds i64, ptr %ptr, i64 2
|
|
%val0 = load volatile i64, ptr %ptr0
|
|
%val1 = load volatile i64, ptr %ptr1
|
|
%res0 = insertelement <2 x i64> undef, i64 %val0, i32 0
|
|
%res1 = insertelement <2 x i64> %res0, i64 %val1, i32 1
|
|
ret <2 x i64> %res1
|
|
}
|
|
|
|
define <4 x float> @merge_4f32_f32_2345_volatile(ptr %ptr) nounwind uwtable noinline ssp {
|
|
; SSE2-LABEL: merge_4f32_f32_2345_volatile:
|
|
; SSE2: # %bb.0:
|
|
; SSE2-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; SSE2-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
; SSE2-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
|
|
; SSE2-NEXT: retq
|
|
;
|
|
; SSE41-LABEL: merge_4f32_f32_2345_volatile:
|
|
; SSE41: # %bb.0:
|
|
; SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
|
|
; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
|
|
; SSE41-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_2345_volatile:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
|
|
; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: merge_4f32_f32_2345_volatile:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE1-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; X86-SSE1-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
|
|
; X86-SSE1-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
|
|
; X86-SSE1-NEXT: retl
|
|
;
|
|
; X86-SSE41-LABEL: merge_4f32_f32_2345_volatile:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
|
|
; X86-SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
|
|
; X86-SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
|
|
; X86-SSE41-NEXT: retl
|
|
%ptr0 = getelementptr inbounds float, ptr %ptr, i64 2
|
|
%ptr1 = getelementptr inbounds float, ptr %ptr, i64 3
|
|
%ptr2 = getelementptr inbounds float, ptr %ptr, i64 4
|
|
%ptr3 = getelementptr inbounds float, ptr %ptr, i64 5
|
|
%val0 = load volatile float, ptr %ptr0
|
|
%val1 = load float, ptr %ptr1
|
|
%val2 = load float, ptr %ptr2
|
|
%val3 = load float, ptr %ptr3
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float %val1, i32 1
|
|
%res2 = insertelement <4 x float> %res1, float %val2, i32 2
|
|
%res3 = insertelement <4 x float> %res2, float %val3, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
;
|
|
; Non-consecutive test.
|
|
;
|
|
|
|
define <4 x float> @merge_4f32_f32_X0YY(ptr %ptr0, ptr %ptr1) nounwind uwtable noinline ssp {
|
|
; SSE-LABEL: merge_4f32_f32_X0YY:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: merge_4f32_f32_X0YY:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0]
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE-LABEL: merge_4f32_f32_X0YY:
|
|
; X86-SSE: # %bb.0:
|
|
; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
|
|
; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]
|
|
; X86-SSE-NEXT: retl
|
|
%val0 = load float, ptr %ptr0, align 4
|
|
%val1 = load float, ptr %ptr1, align 4
|
|
%res0 = insertelement <4 x float> undef, float %val0, i32 0
|
|
%res1 = insertelement <4 x float> %res0, float 0.000000e+00, i32 1
|
|
%res2 = insertelement <4 x float> %res1, float %val1, i32 2
|
|
%res3 = insertelement <4 x float> %res2, float %val1, i32 3
|
|
ret <4 x float> %res3
|
|
}
|
|
|
|
;
|
|
; Extension tests.
|
|
;
|
|
|
|
; PR31309
|
|
define <4 x i32> @load_i32_zext_i128_v4i32(ptr %ptr) {
|
|
; SSE-LABEL: load_i32_zext_i128_v4i32:
|
|
; SSE: # %bb.0:
|
|
; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; SSE-NEXT: retq
|
|
;
|
|
; AVX-LABEL: load_i32_zext_i128_v4i32:
|
|
; AVX: # %bb.0:
|
|
; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; AVX-NEXT: retq
|
|
;
|
|
; X86-SSE1-LABEL: load_i32_zext_i128_v4i32:
|
|
; X86-SSE1: # %bb.0:
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE1-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X86-SSE1-NEXT: movl (%ecx), %ecx
|
|
; X86-SSE1-NEXT: movl %ecx, (%eax)
|
|
; X86-SSE1-NEXT: movl $0, 12(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 8(%eax)
|
|
; X86-SSE1-NEXT: movl $0, 4(%eax)
|
|
; X86-SSE1-NEXT: retl $4
|
|
;
|
|
; X86-SSE41-LABEL: load_i32_zext_i128_v4i32:
|
|
; X86-SSE41: # %bb.0:
|
|
; X86-SSE41-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X86-SSE41-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; X86-SSE41-NEXT: retl
|
|
%1 = load i32, ptr %ptr
|
|
%2 = zext i32 %1 to i128
|
|
%3 = bitcast i128 %2 to <4 x i32>
|
|
ret <4 x i32> %3
|
|
}
|