| ; 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-prefix=ANY --check-prefix=NO512 --check-prefix=SSE2 |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.1 | FileCheck %s --check-prefix=ANY --check-prefix=NO512 --check-prefix=SSE41 |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx | FileCheck %s --check-prefix=ANY --check-prefix=NO512 --check-prefix=AVXANY --check-prefix=AVX1 |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx2 | FileCheck %s --check-prefix=ANY --check-prefix=NO512 --check-prefix=AVXANY --check-prefix=AVX2 |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx512f | FileCheck %s --check-prefix=ANY --check-prefix=AVXANY --check-prefix=AVX512 --check-prefix=AVX512F |
| ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx512bw | FileCheck %s --check-prefix=ANY --check-prefix=AVXANY --check-prefix=AVX512 --check-prefix=AVX512BW |
| |
| ; Equality checks of 128/256-bit values can use PMOVMSK or PTEST to avoid scalarization. |
| |
| define i32 @ne_i128(<2 x i64> %x, <2 x i64> %y) { |
| ; SSE2-LABEL: ne_i128: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pcmpeqb %xmm1, %xmm0 |
| ; SSE2-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: cmpl $65535, %ecx # imm = 0xFFFF |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: ne_i128: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: pxor %xmm1, %xmm0 |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: ptest %xmm0, %xmm0 |
| ; SSE41-NEXT: setne %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVXANY-LABEL: ne_i128: |
| ; AVXANY: # %bb.0: |
| ; AVXANY-NEXT: vpxor %xmm1, %xmm0, %xmm0 |
| ; AVXANY-NEXT: xorl %eax, %eax |
| ; AVXANY-NEXT: vptest %xmm0, %xmm0 |
| ; AVXANY-NEXT: setne %al |
| ; AVXANY-NEXT: retq |
| %bcx = bitcast <2 x i64> %x to i128 |
| %bcy = bitcast <2 x i64> %y to i128 |
| %cmp = icmp ne i128 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| define i32 @eq_i128(<2 x i64> %x, <2 x i64> %y) { |
| ; SSE2-LABEL: eq_i128: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pcmpeqb %xmm1, %xmm0 |
| ; SSE2-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: cmpl $65535, %ecx # imm = 0xFFFF |
| ; SSE2-NEXT: sete %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: eq_i128: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: pxor %xmm1, %xmm0 |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: ptest %xmm0, %xmm0 |
| ; SSE41-NEXT: sete %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVXANY-LABEL: eq_i128: |
| ; AVXANY: # %bb.0: |
| ; AVXANY-NEXT: vpxor %xmm1, %xmm0, %xmm0 |
| ; AVXANY-NEXT: xorl %eax, %eax |
| ; AVXANY-NEXT: vptest %xmm0, %xmm0 |
| ; AVXANY-NEXT: sete %al |
| ; AVXANY-NEXT: retq |
| %bcx = bitcast <2 x i64> %x to i128 |
| %bcy = bitcast <2 x i64> %y to i128 |
| %cmp = icmp eq i128 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| define i32 @ne_i256(<4 x i64> %x, <4 x i64> %y) { |
| ; SSE2-LABEL: ne_i256: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm4, %rax |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm4, %rcx |
| ; SSE2-NEXT: movq %xmm0, %rdx |
| ; SSE2-NEXT: movq %xmm1, %r8 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdi |
| ; SSE2-NEXT: xorq %rax, %rdi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rsi |
| ; SSE2-NEXT: xorq %rcx, %rsi |
| ; SSE2-NEXT: orq %rdi, %rsi |
| ; SSE2-NEXT: movq %xmm2, %rax |
| ; SSE2-NEXT: xorq %rdx, %rax |
| ; SSE2-NEXT: movq %xmm3, %rcx |
| ; SSE2-NEXT: xorq %r8, %rcx |
| ; SSE2-NEXT: orq %rax, %rcx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rsi, %rcx |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: ne_i256: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq %xmm0, %rax |
| ; SSE41-NEXT: movq %xmm1, %rcx |
| ; SSE41-NEXT: pextrq $1, %xmm0, %rdx |
| ; SSE41-NEXT: pextrq $1, %xmm1, %r8 |
| ; SSE41-NEXT: movq %xmm2, %rdi |
| ; SSE41-NEXT: xorq %rax, %rdi |
| ; SSE41-NEXT: movq %xmm3, %rsi |
| ; SSE41-NEXT: xorq %rcx, %rsi |
| ; SSE41-NEXT: orq %rdi, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm2, %rax |
| ; SSE41-NEXT: xorq %rdx, %rax |
| ; SSE41-NEXT: pextrq $1, %xmm3, %rcx |
| ; SSE41-NEXT: xorq %r8, %rcx |
| ; SSE41-NEXT: orq %rax, %rcx |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rsi, %rcx |
| ; SSE41-NEXT: setne %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: ne_i256: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vptest %ymm0, %ymm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: ne_i256: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vptest %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: ne_i256: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpxor %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vptest %ymm0, %ymm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %bcx = bitcast <4 x i64> %x to i256 |
| %bcy = bitcast <4 x i64> %y to i256 |
| %cmp = icmp ne i256 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| define i32 @eq_i256(<4 x i64> %x, <4 x i64> %y) { |
| ; SSE2-LABEL: eq_i256: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm4, %rax |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm4, %rcx |
| ; SSE2-NEXT: movq %xmm0, %rdx |
| ; SSE2-NEXT: movq %xmm1, %r8 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdi |
| ; SSE2-NEXT: xorq %rax, %rdi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rsi |
| ; SSE2-NEXT: xorq %rcx, %rsi |
| ; SSE2-NEXT: orq %rdi, %rsi |
| ; SSE2-NEXT: movq %xmm2, %rax |
| ; SSE2-NEXT: xorq %rdx, %rax |
| ; SSE2-NEXT: movq %xmm3, %rcx |
| ; SSE2-NEXT: xorq %r8, %rcx |
| ; SSE2-NEXT: orq %rax, %rcx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rsi, %rcx |
| ; SSE2-NEXT: sete %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: eq_i256: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq %xmm0, %rax |
| ; SSE41-NEXT: movq %xmm1, %rcx |
| ; SSE41-NEXT: pextrq $1, %xmm0, %rdx |
| ; SSE41-NEXT: pextrq $1, %xmm1, %r8 |
| ; SSE41-NEXT: movq %xmm2, %rdi |
| ; SSE41-NEXT: xorq %rax, %rdi |
| ; SSE41-NEXT: movq %xmm3, %rsi |
| ; SSE41-NEXT: xorq %rcx, %rsi |
| ; SSE41-NEXT: orq %rdi, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm2, %rax |
| ; SSE41-NEXT: xorq %rdx, %rax |
| ; SSE41-NEXT: pextrq $1, %xmm3, %rcx |
| ; SSE41-NEXT: xorq %r8, %rcx |
| ; SSE41-NEXT: orq %rax, %rcx |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rsi, %rcx |
| ; SSE41-NEXT: sete %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: eq_i256: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vptest %ymm0, %ymm0 |
| ; AVX1-NEXT: sete %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: eq_i256: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vptest %ymm0, %ymm0 |
| ; AVX2-NEXT: sete %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: eq_i256: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpxor %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vptest %ymm0, %ymm0 |
| ; AVX512-NEXT: sete %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %bcx = bitcast <4 x i64> %x to i256 |
| %bcy = bitcast <4 x i64> %y to i256 |
| %cmp = icmp eq i256 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| define i32 @ne_i512(<8 x i64> %x, <8 x i64> %y) { |
| ; SSE2-LABEL: ne_i512: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm0[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rdx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm2[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rsi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm1[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rdi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rax |
| ; SSE2-NEXT: movq %xmm0, %r11 |
| ; SSE2-NEXT: movq %xmm2, %r10 |
| ; SSE2-NEXT: movq %xmm1, %r9 |
| ; SSE2-NEXT: movq %xmm3, %r8 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rcx |
| ; SSE2-NEXT: xorq %rdx, %rcx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdx |
| ; SSE2-NEXT: xorq %rsi, %rdx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rsi |
| ; SSE2-NEXT: xorq %rdi, %rsi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdi |
| ; SSE2-NEXT: xorq %rax, %rdi |
| ; SSE2-NEXT: orq %rsi, %rdi |
| ; SSE2-NEXT: orq %rdx, %rdi |
| ; SSE2-NEXT: orq %rcx, %rdi |
| ; SSE2-NEXT: movq %xmm4, %rax |
| ; SSE2-NEXT: xorq %r11, %rax |
| ; SSE2-NEXT: movq %xmm6, %rcx |
| ; SSE2-NEXT: xorq %r10, %rcx |
| ; SSE2-NEXT: movq %xmm5, %rdx |
| ; SSE2-NEXT: xorq %r9, %rdx |
| ; SSE2-NEXT: movq %xmm7, %rsi |
| ; SSE2-NEXT: xorq %r8, %rsi |
| ; SSE2-NEXT: orq %rdx, %rsi |
| ; SSE2-NEXT: orq %rcx, %rsi |
| ; SSE2-NEXT: orq %rax, %rsi |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rdi, %rsi |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: ne_i512: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq %xmm0, %rax |
| ; SSE41-NEXT: movq %xmm2, %rcx |
| ; SSE41-NEXT: movq %xmm1, %rdx |
| ; SSE41-NEXT: movq %xmm3, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm0, %r11 |
| ; SSE41-NEXT: pextrq $1, %xmm2, %r8 |
| ; SSE41-NEXT: pextrq $1, %xmm1, %r9 |
| ; SSE41-NEXT: pextrq $1, %xmm3, %r10 |
| ; SSE41-NEXT: movq %xmm4, %rdi |
| ; SSE41-NEXT: xorq %rax, %rdi |
| ; SSE41-NEXT: movq %xmm6, %rax |
| ; SSE41-NEXT: xorq %rcx, %rax |
| ; SSE41-NEXT: movq %xmm5, %rcx |
| ; SSE41-NEXT: xorq %rdx, %rcx |
| ; SSE41-NEXT: movq %xmm7, %rdx |
| ; SSE41-NEXT: xorq %rsi, %rdx |
| ; SSE41-NEXT: orq %rcx, %rdx |
| ; SSE41-NEXT: orq %rax, %rdx |
| ; SSE41-NEXT: orq %rdi, %rdx |
| ; SSE41-NEXT: pextrq $1, %xmm4, %rax |
| ; SSE41-NEXT: xorq %r11, %rax |
| ; SSE41-NEXT: pextrq $1, %xmm6, %rcx |
| ; SSE41-NEXT: xorq %r8, %rcx |
| ; SSE41-NEXT: pextrq $1, %xmm5, %rsi |
| ; SSE41-NEXT: xorq %r9, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm7, %rdi |
| ; SSE41-NEXT: xorq %r10, %rdi |
| ; SSE41-NEXT: orq %rsi, %rdi |
| ; SSE41-NEXT: orq %rcx, %rdi |
| ; SSE41-NEXT: orq %rax, %rdi |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rdx, %rdi |
| ; SSE41-NEXT: setne %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: ne_i512: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vmovq %xmm0, %rdx |
| ; AVX1-NEXT: vmovq %xmm1, %rsi |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 |
| ; AVX1-NEXT: vmovq %xmm4, %rdi |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 |
| ; AVX1-NEXT: vmovq %xmm5, %rax |
| ; AVX1-NEXT: vpextrq $1, %xmm0, %r11 |
| ; AVX1-NEXT: vpextrq $1, %xmm1, %r10 |
| ; AVX1-NEXT: vpextrq $1, %xmm4, %r9 |
| ; AVX1-NEXT: vpextrq $1, %xmm5, %r8 |
| ; AVX1-NEXT: vmovq %xmm2, %rcx |
| ; AVX1-NEXT: xorq %rdx, %rcx |
| ; AVX1-NEXT: vmovq %xmm3, %rdx |
| ; AVX1-NEXT: xorq %rsi, %rdx |
| ; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm0 |
| ; AVX1-NEXT: vmovq %xmm0, %rsi |
| ; AVX1-NEXT: xorq %rdi, %rsi |
| ; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm1 |
| ; AVX1-NEXT: vmovq %xmm1, %rdi |
| ; AVX1-NEXT: xorq %rax, %rdi |
| ; AVX1-NEXT: orq %rsi, %rdi |
| ; AVX1-NEXT: orq %rdx, %rdi |
| ; AVX1-NEXT: orq %rcx, %rdi |
| ; AVX1-NEXT: vpextrq $1, %xmm2, %rax |
| ; AVX1-NEXT: xorq %r11, %rax |
| ; AVX1-NEXT: vpextrq $1, %xmm3, %rcx |
| ; AVX1-NEXT: xorq %r10, %rcx |
| ; AVX1-NEXT: vpextrq $1, %xmm0, %rdx |
| ; AVX1-NEXT: xorq %r9, %rdx |
| ; AVX1-NEXT: vpextrq $1, %xmm1, %rsi |
| ; AVX1-NEXT: xorq %r8, %rsi |
| ; AVX1-NEXT: orq %rdx, %rsi |
| ; AVX1-NEXT: orq %rcx, %rsi |
| ; AVX1-NEXT: orq %rax, %rsi |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: orq %rdi, %rsi |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: ne_i512: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vmovq %xmm0, %rdx |
| ; AVX2-NEXT: vmovq %xmm1, %rsi |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm4 |
| ; AVX2-NEXT: vmovq %xmm4, %rdi |
| ; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm5 |
| ; AVX2-NEXT: vmovq %xmm5, %rax |
| ; AVX2-NEXT: vpextrq $1, %xmm0, %r11 |
| ; AVX2-NEXT: vpextrq $1, %xmm1, %r10 |
| ; AVX2-NEXT: vpextrq $1, %xmm4, %r9 |
| ; AVX2-NEXT: vpextrq $1, %xmm5, %r8 |
| ; AVX2-NEXT: vmovq %xmm2, %rcx |
| ; AVX2-NEXT: xorq %rdx, %rcx |
| ; AVX2-NEXT: vmovq %xmm3, %rdx |
| ; AVX2-NEXT: xorq %rsi, %rdx |
| ; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm0 |
| ; AVX2-NEXT: vmovq %xmm0, %rsi |
| ; AVX2-NEXT: xorq %rdi, %rsi |
| ; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm1 |
| ; AVX2-NEXT: vmovq %xmm1, %rdi |
| ; AVX2-NEXT: xorq %rax, %rdi |
| ; AVX2-NEXT: orq %rsi, %rdi |
| ; AVX2-NEXT: orq %rdx, %rdi |
| ; AVX2-NEXT: orq %rcx, %rdi |
| ; AVX2-NEXT: vpextrq $1, %xmm2, %rax |
| ; AVX2-NEXT: xorq %r11, %rax |
| ; AVX2-NEXT: vpextrq $1, %xmm3, %rcx |
| ; AVX2-NEXT: xorq %r10, %rcx |
| ; AVX2-NEXT: vpextrq $1, %xmm0, %rdx |
| ; AVX2-NEXT: xorq %r9, %rdx |
| ; AVX2-NEXT: vpextrq $1, %xmm1, %rsi |
| ; AVX2-NEXT: xorq %r8, %rsi |
| ; AVX2-NEXT: orq %rdx, %rsi |
| ; AVX2-NEXT: orq %rcx, %rsi |
| ; AVX2-NEXT: orq %rax, %rsi |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: orq %rdi, %rsi |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512F-LABEL: ne_i512: |
| ; AVX512F: # %bb.0: |
| ; AVX512F-NEXT: vpcmpneqd %zmm1, %zmm0, %k0 |
| ; AVX512F-NEXT: xorl %eax, %eax |
| ; AVX512F-NEXT: kortestw %k0, %k0 |
| ; AVX512F-NEXT: setne %al |
| ; AVX512F-NEXT: vzeroupper |
| ; AVX512F-NEXT: retq |
| ; |
| ; AVX512BW-LABEL: ne_i512: |
| ; AVX512BW: # %bb.0: |
| ; AVX512BW-NEXT: vpcmpneqb %zmm1, %zmm0, %k0 |
| ; AVX512BW-NEXT: xorl %eax, %eax |
| ; AVX512BW-NEXT: kortestq %k0, %k0 |
| ; AVX512BW-NEXT: setne %al |
| ; AVX512BW-NEXT: vzeroupper |
| ; AVX512BW-NEXT: retq |
| %bcx = bitcast <8 x i64> %x to i512 |
| %bcy = bitcast <8 x i64> %y to i512 |
| %cmp = icmp ne i512 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| define i32 @eq_i512(<8 x i64> %x, <8 x i64> %y) { |
| ; SSE2-LABEL: eq_i512: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm0[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rdx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm2[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rsi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm1[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rdi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm8, %rax |
| ; SSE2-NEXT: movq %xmm0, %r11 |
| ; SSE2-NEXT: movq %xmm2, %r10 |
| ; SSE2-NEXT: movq %xmm1, %r9 |
| ; SSE2-NEXT: movq %xmm3, %r8 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rcx |
| ; SSE2-NEXT: xorq %rdx, %rcx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdx |
| ; SSE2-NEXT: xorq %rsi, %rdx |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rsi |
| ; SSE2-NEXT: xorq %rdi, %rsi |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] |
| ; SSE2-NEXT: movq %xmm0, %rdi |
| ; SSE2-NEXT: xorq %rax, %rdi |
| ; SSE2-NEXT: orq %rsi, %rdi |
| ; SSE2-NEXT: orq %rdx, %rdi |
| ; SSE2-NEXT: orq %rcx, %rdi |
| ; SSE2-NEXT: movq %xmm4, %rax |
| ; SSE2-NEXT: xorq %r11, %rax |
| ; SSE2-NEXT: movq %xmm6, %rcx |
| ; SSE2-NEXT: xorq %r10, %rcx |
| ; SSE2-NEXT: movq %xmm5, %rdx |
| ; SSE2-NEXT: xorq %r9, %rdx |
| ; SSE2-NEXT: movq %xmm7, %rsi |
| ; SSE2-NEXT: xorq %r8, %rsi |
| ; SSE2-NEXT: orq %rdx, %rsi |
| ; SSE2-NEXT: orq %rcx, %rsi |
| ; SSE2-NEXT: orq %rax, %rsi |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rdi, %rsi |
| ; SSE2-NEXT: sete %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: eq_i512: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq %xmm0, %rax |
| ; SSE41-NEXT: movq %xmm2, %rcx |
| ; SSE41-NEXT: movq %xmm1, %rdx |
| ; SSE41-NEXT: movq %xmm3, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm0, %r11 |
| ; SSE41-NEXT: pextrq $1, %xmm2, %r8 |
| ; SSE41-NEXT: pextrq $1, %xmm1, %r9 |
| ; SSE41-NEXT: pextrq $1, %xmm3, %r10 |
| ; SSE41-NEXT: movq %xmm4, %rdi |
| ; SSE41-NEXT: xorq %rax, %rdi |
| ; SSE41-NEXT: movq %xmm6, %rax |
| ; SSE41-NEXT: xorq %rcx, %rax |
| ; SSE41-NEXT: movq %xmm5, %rcx |
| ; SSE41-NEXT: xorq %rdx, %rcx |
| ; SSE41-NEXT: movq %xmm7, %rdx |
| ; SSE41-NEXT: xorq %rsi, %rdx |
| ; SSE41-NEXT: orq %rcx, %rdx |
| ; SSE41-NEXT: orq %rax, %rdx |
| ; SSE41-NEXT: orq %rdi, %rdx |
| ; SSE41-NEXT: pextrq $1, %xmm4, %rax |
| ; SSE41-NEXT: xorq %r11, %rax |
| ; SSE41-NEXT: pextrq $1, %xmm6, %rcx |
| ; SSE41-NEXT: xorq %r8, %rcx |
| ; SSE41-NEXT: pextrq $1, %xmm5, %rsi |
| ; SSE41-NEXT: xorq %r9, %rsi |
| ; SSE41-NEXT: pextrq $1, %xmm7, %rdi |
| ; SSE41-NEXT: xorq %r10, %rdi |
| ; SSE41-NEXT: orq %rsi, %rdi |
| ; SSE41-NEXT: orq %rcx, %rdi |
| ; SSE41-NEXT: orq %rax, %rdi |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rdx, %rdi |
| ; SSE41-NEXT: sete %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: eq_i512: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vmovq %xmm0, %rdx |
| ; AVX1-NEXT: vmovq %xmm1, %rsi |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 |
| ; AVX1-NEXT: vmovq %xmm4, %rdi |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 |
| ; AVX1-NEXT: vmovq %xmm5, %rax |
| ; AVX1-NEXT: vpextrq $1, %xmm0, %r11 |
| ; AVX1-NEXT: vpextrq $1, %xmm1, %r10 |
| ; AVX1-NEXT: vpextrq $1, %xmm4, %r9 |
| ; AVX1-NEXT: vpextrq $1, %xmm5, %r8 |
| ; AVX1-NEXT: vmovq %xmm2, %rcx |
| ; AVX1-NEXT: xorq %rdx, %rcx |
| ; AVX1-NEXT: vmovq %xmm3, %rdx |
| ; AVX1-NEXT: xorq %rsi, %rdx |
| ; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm0 |
| ; AVX1-NEXT: vmovq %xmm0, %rsi |
| ; AVX1-NEXT: xorq %rdi, %rsi |
| ; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm1 |
| ; AVX1-NEXT: vmovq %xmm1, %rdi |
| ; AVX1-NEXT: xorq %rax, %rdi |
| ; AVX1-NEXT: orq %rsi, %rdi |
| ; AVX1-NEXT: orq %rdx, %rdi |
| ; AVX1-NEXT: orq %rcx, %rdi |
| ; AVX1-NEXT: vpextrq $1, %xmm2, %rax |
| ; AVX1-NEXT: xorq %r11, %rax |
| ; AVX1-NEXT: vpextrq $1, %xmm3, %rcx |
| ; AVX1-NEXT: xorq %r10, %rcx |
| ; AVX1-NEXT: vpextrq $1, %xmm0, %rdx |
| ; AVX1-NEXT: xorq %r9, %rdx |
| ; AVX1-NEXT: vpextrq $1, %xmm1, %rsi |
| ; AVX1-NEXT: xorq %r8, %rsi |
| ; AVX1-NEXT: orq %rdx, %rsi |
| ; AVX1-NEXT: orq %rcx, %rsi |
| ; AVX1-NEXT: orq %rax, %rsi |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: orq %rdi, %rsi |
| ; AVX1-NEXT: sete %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: eq_i512: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vmovq %xmm0, %rdx |
| ; AVX2-NEXT: vmovq %xmm1, %rsi |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm4 |
| ; AVX2-NEXT: vmovq %xmm4, %rdi |
| ; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm5 |
| ; AVX2-NEXT: vmovq %xmm5, %rax |
| ; AVX2-NEXT: vpextrq $1, %xmm0, %r11 |
| ; AVX2-NEXT: vpextrq $1, %xmm1, %r10 |
| ; AVX2-NEXT: vpextrq $1, %xmm4, %r9 |
| ; AVX2-NEXT: vpextrq $1, %xmm5, %r8 |
| ; AVX2-NEXT: vmovq %xmm2, %rcx |
| ; AVX2-NEXT: xorq %rdx, %rcx |
| ; AVX2-NEXT: vmovq %xmm3, %rdx |
| ; AVX2-NEXT: xorq %rsi, %rdx |
| ; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm0 |
| ; AVX2-NEXT: vmovq %xmm0, %rsi |
| ; AVX2-NEXT: xorq %rdi, %rsi |
| ; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm1 |
| ; AVX2-NEXT: vmovq %xmm1, %rdi |
| ; AVX2-NEXT: xorq %rax, %rdi |
| ; AVX2-NEXT: orq %rsi, %rdi |
| ; AVX2-NEXT: orq %rdx, %rdi |
| ; AVX2-NEXT: orq %rcx, %rdi |
| ; AVX2-NEXT: vpextrq $1, %xmm2, %rax |
| ; AVX2-NEXT: xorq %r11, %rax |
| ; AVX2-NEXT: vpextrq $1, %xmm3, %rcx |
| ; AVX2-NEXT: xorq %r10, %rcx |
| ; AVX2-NEXT: vpextrq $1, %xmm0, %rdx |
| ; AVX2-NEXT: xorq %r9, %rdx |
| ; AVX2-NEXT: vpextrq $1, %xmm1, %rsi |
| ; AVX2-NEXT: xorq %r8, %rsi |
| ; AVX2-NEXT: orq %rdx, %rsi |
| ; AVX2-NEXT: orq %rcx, %rsi |
| ; AVX2-NEXT: orq %rax, %rsi |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: orq %rdi, %rsi |
| ; AVX2-NEXT: sete %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512F-LABEL: eq_i512: |
| ; AVX512F: # %bb.0: |
| ; AVX512F-NEXT: vpcmpneqd %zmm1, %zmm0, %k0 |
| ; AVX512F-NEXT: xorl %eax, %eax |
| ; AVX512F-NEXT: kortestw %k0, %k0 |
| ; AVX512F-NEXT: sete %al |
| ; AVX512F-NEXT: vzeroupper |
| ; AVX512F-NEXT: retq |
| ; |
| ; AVX512BW-LABEL: eq_i512: |
| ; AVX512BW: # %bb.0: |
| ; AVX512BW-NEXT: vpcmpneqb %zmm1, %zmm0, %k0 |
| ; AVX512BW-NEXT: xorl %eax, %eax |
| ; AVX512BW-NEXT: kortestq %k0, %k0 |
| ; AVX512BW-NEXT: sete %al |
| ; AVX512BW-NEXT: vzeroupper |
| ; AVX512BW-NEXT: retq |
| %bcx = bitcast <8 x i64> %x to i512 |
| %bcy = bitcast <8 x i64> %y to i512 |
| %cmp = icmp eq i512 %bcx, %bcy |
| %zext = zext i1 %cmp to i32 |
| ret i32 %zext |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 32) != 0' |
| ; if we allowed 2 pairs of 16-byte loads per block. |
| |
| define i32 @ne_i128_pair(i128* %a, i128* %b) { |
| ; SSE2-LABEL: ne_i128_pair: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqu (%rdi), %xmm0 |
| ; SSE2-NEXT: movdqu 16(%rdi), %xmm1 |
| ; SSE2-NEXT: movdqu (%rsi), %xmm2 |
| ; SSE2-NEXT: pcmpeqb %xmm0, %xmm2 |
| ; SSE2-NEXT: movdqu 16(%rsi), %xmm0 |
| ; SSE2-NEXT: pcmpeqb %xmm1, %xmm0 |
| ; SSE2-NEXT: pand %xmm2, %xmm0 |
| ; SSE2-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: cmpl $65535, %ecx # imm = 0xFFFF |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: ne_i128_pair: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movdqu (%rdi), %xmm0 |
| ; SSE41-NEXT: movdqu 16(%rdi), %xmm1 |
| ; SSE41-NEXT: movdqu (%rsi), %xmm2 |
| ; SSE41-NEXT: pxor %xmm0, %xmm2 |
| ; SSE41-NEXT: movdqu 16(%rsi), %xmm0 |
| ; SSE41-NEXT: pxor %xmm1, %xmm0 |
| ; SSE41-NEXT: por %xmm2, %xmm0 |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: ptest %xmm0, %xmm0 |
| ; SSE41-NEXT: setne %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVXANY-LABEL: ne_i128_pair: |
| ; AVXANY: # %bb.0: |
| ; AVXANY-NEXT: vmovdqu (%rdi), %xmm0 |
| ; AVXANY-NEXT: vmovdqu 16(%rdi), %xmm1 |
| ; AVXANY-NEXT: vpxor 16(%rsi), %xmm1, %xmm1 |
| ; AVXANY-NEXT: vpxor (%rsi), %xmm0, %xmm0 |
| ; AVXANY-NEXT: vpor %xmm1, %xmm0, %xmm0 |
| ; AVXANY-NEXT: xorl %eax, %eax |
| ; AVXANY-NEXT: vptest %xmm0, %xmm0 |
| ; AVXANY-NEXT: setne %al |
| ; AVXANY-NEXT: retq |
| %a0 = load i128, i128* %a |
| %b0 = load i128, i128* %b |
| %xor1 = xor i128 %a0, %b0 |
| %ap1 = getelementptr i128, i128* %a, i128 1 |
| %bp1 = getelementptr i128, i128* %b, i128 1 |
| %a1 = load i128, i128* %ap1 |
| %b1 = load i128, i128* %bp1 |
| %xor2 = xor i128 %a1, %b1 |
| %or = or i128 %xor1, %xor2 |
| %cmp = icmp ne i128 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 32) == 0' |
| ; if we allowed 2 pairs of 16-byte loads per block. |
| |
| define i32 @eq_i128_pair(i128* %a, i128* %b) { |
| ; SSE2-LABEL: eq_i128_pair: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqu (%rdi), %xmm0 |
| ; SSE2-NEXT: movdqu 16(%rdi), %xmm1 |
| ; SSE2-NEXT: movdqu (%rsi), %xmm2 |
| ; SSE2-NEXT: pcmpeqb %xmm0, %xmm2 |
| ; SSE2-NEXT: movdqu 16(%rsi), %xmm0 |
| ; SSE2-NEXT: pcmpeqb %xmm1, %xmm0 |
| ; SSE2-NEXT: pand %xmm2, %xmm0 |
| ; SSE2-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: cmpl $65535, %ecx # imm = 0xFFFF |
| ; SSE2-NEXT: sete %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: eq_i128_pair: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movdqu (%rdi), %xmm0 |
| ; SSE41-NEXT: movdqu 16(%rdi), %xmm1 |
| ; SSE41-NEXT: movdqu (%rsi), %xmm2 |
| ; SSE41-NEXT: pxor %xmm0, %xmm2 |
| ; SSE41-NEXT: movdqu 16(%rsi), %xmm0 |
| ; SSE41-NEXT: pxor %xmm1, %xmm0 |
| ; SSE41-NEXT: por %xmm2, %xmm0 |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: ptest %xmm0, %xmm0 |
| ; SSE41-NEXT: sete %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVXANY-LABEL: eq_i128_pair: |
| ; AVXANY: # %bb.0: |
| ; AVXANY-NEXT: vmovdqu (%rdi), %xmm0 |
| ; AVXANY-NEXT: vmovdqu 16(%rdi), %xmm1 |
| ; AVXANY-NEXT: vpxor 16(%rsi), %xmm1, %xmm1 |
| ; AVXANY-NEXT: vpxor (%rsi), %xmm0, %xmm0 |
| ; AVXANY-NEXT: vpor %xmm1, %xmm0, %xmm0 |
| ; AVXANY-NEXT: xorl %eax, %eax |
| ; AVXANY-NEXT: vptest %xmm0, %xmm0 |
| ; AVXANY-NEXT: sete %al |
| ; AVXANY-NEXT: retq |
| %a0 = load i128, i128* %a |
| %b0 = load i128, i128* %b |
| %xor1 = xor i128 %a0, %b0 |
| %ap1 = getelementptr i128, i128* %a, i128 1 |
| %bp1 = getelementptr i128, i128* %b, i128 1 |
| %a1 = load i128, i128* %ap1 |
| %b1 = load i128, i128* %bp1 |
| %xor2 = xor i128 %a1, %b1 |
| %or = or i128 %xor1, %xor2 |
| %cmp = icmp eq i128 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 64) != 0' |
| ; if we allowed 2 pairs of 32-byte loads per block. |
| |
| define i32 @ne_i256_pair(i256* %a, i256* %b) { |
| ; SSE2-LABEL: ne_i256_pair: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movq 16(%rdi), %r9 |
| ; SSE2-NEXT: movq 24(%rdi), %r11 |
| ; SSE2-NEXT: movq (%rdi), %r8 |
| ; SSE2-NEXT: movq 8(%rdi), %r10 |
| ; SSE2-NEXT: xorq 8(%rsi), %r10 |
| ; SSE2-NEXT: xorq 24(%rsi), %r11 |
| ; SSE2-NEXT: xorq (%rsi), %r8 |
| ; SSE2-NEXT: xorq 16(%rsi), %r9 |
| ; SSE2-NEXT: movq 48(%rdi), %rcx |
| ; SSE2-NEXT: movq 32(%rdi), %rax |
| ; SSE2-NEXT: movq 56(%rdi), %rdx |
| ; SSE2-NEXT: movq 40(%rdi), %rdi |
| ; SSE2-NEXT: xorq 40(%rsi), %rdi |
| ; SSE2-NEXT: xorq 56(%rsi), %rdx |
| ; SSE2-NEXT: orq %r11, %rdx |
| ; SSE2-NEXT: orq %rdi, %rdx |
| ; SSE2-NEXT: orq %r10, %rdx |
| ; SSE2-NEXT: xorq 32(%rsi), %rax |
| ; SSE2-NEXT: xorq 48(%rsi), %rcx |
| ; SSE2-NEXT: orq %r9, %rcx |
| ; SSE2-NEXT: orq %rax, %rcx |
| ; SSE2-NEXT: orq %r8, %rcx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rdx, %rcx |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: ne_i256_pair: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq 16(%rdi), %r9 |
| ; SSE41-NEXT: movq 24(%rdi), %r11 |
| ; SSE41-NEXT: movq (%rdi), %r8 |
| ; SSE41-NEXT: movq 8(%rdi), %r10 |
| ; SSE41-NEXT: xorq 8(%rsi), %r10 |
| ; SSE41-NEXT: xorq 24(%rsi), %r11 |
| ; SSE41-NEXT: xorq (%rsi), %r8 |
| ; SSE41-NEXT: xorq 16(%rsi), %r9 |
| ; SSE41-NEXT: movq 48(%rdi), %rcx |
| ; SSE41-NEXT: movq 32(%rdi), %rax |
| ; SSE41-NEXT: movq 56(%rdi), %rdx |
| ; SSE41-NEXT: movq 40(%rdi), %rdi |
| ; SSE41-NEXT: xorq 40(%rsi), %rdi |
| ; SSE41-NEXT: xorq 56(%rsi), %rdx |
| ; SSE41-NEXT: orq %r11, %rdx |
| ; SSE41-NEXT: orq %rdi, %rdx |
| ; SSE41-NEXT: orq %r10, %rdx |
| ; SSE41-NEXT: xorq 32(%rsi), %rax |
| ; SSE41-NEXT: xorq 48(%rsi), %rcx |
| ; SSE41-NEXT: orq %r9, %rcx |
| ; SSE41-NEXT: orq %rax, %rcx |
| ; SSE41-NEXT: orq %r8, %rcx |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rdx, %rcx |
| ; SSE41-NEXT: setne %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: ne_i256_pair: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vmovups (%rdi), %ymm0 |
| ; AVX1-NEXT: vmovups 32(%rdi), %ymm1 |
| ; AVX1-NEXT: vxorps 32(%rsi), %ymm1, %ymm1 |
| ; AVX1-NEXT: vxorps (%rsi), %ymm0, %ymm0 |
| ; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vptest %ymm0, %ymm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: ne_i256_pair: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vmovdqu (%rdi), %ymm0 |
| ; AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 |
| ; AVX2-NEXT: vpxor 32(%rsi), %ymm1, %ymm1 |
| ; AVX2-NEXT: vpxor (%rsi), %ymm0, %ymm0 |
| ; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vptest %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: ne_i256_pair: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vmovdqu (%rdi), %ymm0 |
| ; AVX512-NEXT: vmovdqu 32(%rdi), %ymm1 |
| ; AVX512-NEXT: vpxor 32(%rsi), %ymm1, %ymm1 |
| ; AVX512-NEXT: vpxor (%rsi), %ymm0, %ymm0 |
| ; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vptest %ymm0, %ymm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a0 = load i256, i256* %a |
| %b0 = load i256, i256* %b |
| %xor1 = xor i256 %a0, %b0 |
| %ap1 = getelementptr i256, i256* %a, i256 1 |
| %bp1 = getelementptr i256, i256* %b, i256 1 |
| %a1 = load i256, i256* %ap1 |
| %b1 = load i256, i256* %bp1 |
| %xor2 = xor i256 %a1, %b1 |
| %or = or i256 %xor1, %xor2 |
| %cmp = icmp ne i256 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 64) == 0' |
| ; if we allowed 2 pairs of 32-byte loads per block. |
| |
| define i32 @eq_i256_pair(i256* %a, i256* %b) { |
| ; SSE2-LABEL: eq_i256_pair: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movq 16(%rdi), %r9 |
| ; SSE2-NEXT: movq 24(%rdi), %r11 |
| ; SSE2-NEXT: movq (%rdi), %r8 |
| ; SSE2-NEXT: movq 8(%rdi), %r10 |
| ; SSE2-NEXT: xorq 8(%rsi), %r10 |
| ; SSE2-NEXT: xorq 24(%rsi), %r11 |
| ; SSE2-NEXT: xorq (%rsi), %r8 |
| ; SSE2-NEXT: xorq 16(%rsi), %r9 |
| ; SSE2-NEXT: movq 48(%rdi), %rcx |
| ; SSE2-NEXT: movq 32(%rdi), %rax |
| ; SSE2-NEXT: movq 56(%rdi), %rdx |
| ; SSE2-NEXT: movq 40(%rdi), %rdi |
| ; SSE2-NEXT: xorq 40(%rsi), %rdi |
| ; SSE2-NEXT: xorq 56(%rsi), %rdx |
| ; SSE2-NEXT: orq %r11, %rdx |
| ; SSE2-NEXT: orq %rdi, %rdx |
| ; SSE2-NEXT: orq %r10, %rdx |
| ; SSE2-NEXT: xorq 32(%rsi), %rax |
| ; SSE2-NEXT: xorq 48(%rsi), %rcx |
| ; SSE2-NEXT: orq %r9, %rcx |
| ; SSE2-NEXT: orq %rax, %rcx |
| ; SSE2-NEXT: orq %r8, %rcx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: orq %rdx, %rcx |
| ; SSE2-NEXT: sete %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE41-LABEL: eq_i256_pair: |
| ; SSE41: # %bb.0: |
| ; SSE41-NEXT: movq 16(%rdi), %r9 |
| ; SSE41-NEXT: movq 24(%rdi), %r11 |
| ; SSE41-NEXT: movq (%rdi), %r8 |
| ; SSE41-NEXT: movq 8(%rdi), %r10 |
| ; SSE41-NEXT: xorq 8(%rsi), %r10 |
| ; SSE41-NEXT: xorq 24(%rsi), %r11 |
| ; SSE41-NEXT: xorq (%rsi), %r8 |
| ; SSE41-NEXT: xorq 16(%rsi), %r9 |
| ; SSE41-NEXT: movq 48(%rdi), %rcx |
| ; SSE41-NEXT: movq 32(%rdi), %rax |
| ; SSE41-NEXT: movq 56(%rdi), %rdx |
| ; SSE41-NEXT: movq 40(%rdi), %rdi |
| ; SSE41-NEXT: xorq 40(%rsi), %rdi |
| ; SSE41-NEXT: xorq 56(%rsi), %rdx |
| ; SSE41-NEXT: orq %r11, %rdx |
| ; SSE41-NEXT: orq %rdi, %rdx |
| ; SSE41-NEXT: orq %r10, %rdx |
| ; SSE41-NEXT: xorq 32(%rsi), %rax |
| ; SSE41-NEXT: xorq 48(%rsi), %rcx |
| ; SSE41-NEXT: orq %r9, %rcx |
| ; SSE41-NEXT: orq %rax, %rcx |
| ; SSE41-NEXT: orq %r8, %rcx |
| ; SSE41-NEXT: xorl %eax, %eax |
| ; SSE41-NEXT: orq %rdx, %rcx |
| ; SSE41-NEXT: sete %al |
| ; SSE41-NEXT: retq |
| ; |
| ; AVX1-LABEL: eq_i256_pair: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vmovups (%rdi), %ymm0 |
| ; AVX1-NEXT: vmovups 32(%rdi), %ymm1 |
| ; AVX1-NEXT: vxorps 32(%rsi), %ymm1, %ymm1 |
| ; AVX1-NEXT: vxorps (%rsi), %ymm0, %ymm0 |
| ; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vptest %ymm0, %ymm0 |
| ; AVX1-NEXT: sete %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: eq_i256_pair: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vmovdqu (%rdi), %ymm0 |
| ; AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 |
| ; AVX2-NEXT: vpxor 32(%rsi), %ymm1, %ymm1 |
| ; AVX2-NEXT: vpxor (%rsi), %ymm0, %ymm0 |
| ; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vptest %ymm0, %ymm0 |
| ; AVX2-NEXT: sete %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: eq_i256_pair: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vmovdqu (%rdi), %ymm0 |
| ; AVX512-NEXT: vmovdqu 32(%rdi), %ymm1 |
| ; AVX512-NEXT: vpxor 32(%rsi), %ymm1, %ymm1 |
| ; AVX512-NEXT: vpxor (%rsi), %ymm0, %ymm0 |
| ; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vptest %ymm0, %ymm0 |
| ; AVX512-NEXT: sete %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a0 = load i256, i256* %a |
| %b0 = load i256, i256* %b |
| %xor1 = xor i256 %a0, %b0 |
| %ap1 = getelementptr i256, i256* %a, i256 1 |
| %bp1 = getelementptr i256, i256* %b, i256 1 |
| %a1 = load i256, i256* %ap1 |
| %b1 = load i256, i256* %bp1 |
| %xor2 = xor i256 %a1, %b1 |
| %or = or i256 %xor1, %xor2 |
| %cmp = icmp eq i256 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 64) != 0' |
| ; if we allowed 2 pairs of 64-byte loads per block. |
| |
| define i32 @ne_i512_pair(i512* %a, i512* %b) { |
| ; NO512-LABEL: ne_i512_pair: |
| ; NO512: # %bb.0: |
| ; NO512-NEXT: movq 32(%rdi), %r8 |
| ; NO512-NEXT: movq 48(%rdi), %r9 |
| ; NO512-NEXT: movq 40(%rdi), %rdx |
| ; NO512-NEXT: movq 56(%rdi), %rcx |
| ; NO512-NEXT: xorq 56(%rsi), %rcx |
| ; NO512-NEXT: movq 120(%rdi), %rax |
| ; NO512-NEXT: xorq 120(%rsi), %rax |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 88(%rdi), %rcx |
| ; NO512-NEXT: xorq 88(%rsi), %rcx |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 24(%rdi), %rcx |
| ; NO512-NEXT: xorq 24(%rsi), %rcx |
| ; NO512-NEXT: xorq 40(%rsi), %rdx |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 104(%rdi), %rcx |
| ; NO512-NEXT: xorq 104(%rsi), %rcx |
| ; NO512-NEXT: orq %rdx, %rcx |
| ; NO512-NEXT: movq 72(%rdi), %rdx |
| ; NO512-NEXT: xorq 72(%rsi), %rdx |
| ; NO512-NEXT: orq %rdx, %rcx |
| ; NO512-NEXT: movq 16(%rdi), %r10 |
| ; NO512-NEXT: orq %rax, %rcx |
| ; NO512-NEXT: movq 8(%rdi), %rax |
| ; NO512-NEXT: xorq 8(%rsi), %rax |
| ; NO512-NEXT: xorq 48(%rsi), %r9 |
| ; NO512-NEXT: orq %rax, %rcx |
| ; NO512-NEXT: movq 112(%rdi), %rax |
| ; NO512-NEXT: xorq 112(%rsi), %rax |
| ; NO512-NEXT: orq %r9, %rax |
| ; NO512-NEXT: movq 80(%rdi), %rdx |
| ; NO512-NEXT: xorq 80(%rsi), %rdx |
| ; NO512-NEXT: orq %rdx, %rax |
| ; NO512-NEXT: movq (%rdi), %r9 |
| ; NO512-NEXT: xorq 16(%rsi), %r10 |
| ; NO512-NEXT: xorq (%rsi), %r9 |
| ; NO512-NEXT: xorq 32(%rsi), %r8 |
| ; NO512-NEXT: orq %r10, %rax |
| ; NO512-NEXT: movq 96(%rdi), %rdx |
| ; NO512-NEXT: movq 64(%rdi), %rdi |
| ; NO512-NEXT: xorq 64(%rsi), %rdi |
| ; NO512-NEXT: xorq 96(%rsi), %rdx |
| ; NO512-NEXT: orq %r8, %rdx |
| ; NO512-NEXT: orq %rdi, %rdx |
| ; NO512-NEXT: orq %rax, %rdx |
| ; NO512-NEXT: orq %r9, %rdx |
| ; NO512-NEXT: xorl %eax, %eax |
| ; NO512-NEXT: orq %rcx, %rdx |
| ; NO512-NEXT: setne %al |
| ; NO512-NEXT: retq |
| ; |
| ; AVX512F-LABEL: ne_i512_pair: |
| ; AVX512F: # %bb.0: |
| ; AVX512F-NEXT: vmovdqu64 (%rdi), %zmm0 |
| ; AVX512F-NEXT: vmovdqu64 64(%rdi), %zmm1 |
| ; AVX512F-NEXT: vpcmpneqd 64(%rsi), %zmm1, %k0 |
| ; AVX512F-NEXT: vpcmpneqd (%rsi), %zmm0, %k1 |
| ; AVX512F-NEXT: xorl %eax, %eax |
| ; AVX512F-NEXT: kortestw %k0, %k1 |
| ; AVX512F-NEXT: setne %al |
| ; AVX512F-NEXT: vzeroupper |
| ; AVX512F-NEXT: retq |
| ; |
| ; AVX512BW-LABEL: ne_i512_pair: |
| ; AVX512BW: # %bb.0: |
| ; AVX512BW-NEXT: vmovdqu64 (%rdi), %zmm0 |
| ; AVX512BW-NEXT: vmovdqu64 64(%rdi), %zmm1 |
| ; AVX512BW-NEXT: vpcmpneqb 64(%rsi), %zmm1, %k0 |
| ; AVX512BW-NEXT: vpcmpneqb (%rsi), %zmm0, %k1 |
| ; AVX512BW-NEXT: xorl %eax, %eax |
| ; AVX512BW-NEXT: kortestq %k0, %k1 |
| ; AVX512BW-NEXT: setne %al |
| ; AVX512BW-NEXT: vzeroupper |
| ; AVX512BW-NEXT: retq |
| %a0 = load i512, i512* %a |
| %b0 = load i512, i512* %b |
| %xor1 = xor i512 %a0, %b0 |
| %ap1 = getelementptr i512, i512* %a, i512 1 |
| %bp1 = getelementptr i512, i512* %b, i512 1 |
| %a1 = load i512, i512* %ap1 |
| %b1 = load i512, i512* %bp1 |
| %xor2 = xor i512 %a1, %b1 |
| %or = or i512 %xor1, %xor2 |
| %cmp = icmp ne i512 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; This test models the expansion of 'memcmp(a, b, 64) == 0' |
| ; if we allowed 2 pairs of 64-byte loads per block. |
| |
| define i32 @eq_i512_pair(i512* %a, i512* %b) { |
| ; NO512-LABEL: eq_i512_pair: |
| ; NO512: # %bb.0: |
| ; NO512-NEXT: movq 32(%rdi), %r8 |
| ; NO512-NEXT: movq 48(%rdi), %r9 |
| ; NO512-NEXT: movq 40(%rdi), %rdx |
| ; NO512-NEXT: movq 56(%rdi), %rcx |
| ; NO512-NEXT: xorq 56(%rsi), %rcx |
| ; NO512-NEXT: movq 120(%rdi), %rax |
| ; NO512-NEXT: xorq 120(%rsi), %rax |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 88(%rdi), %rcx |
| ; NO512-NEXT: xorq 88(%rsi), %rcx |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 24(%rdi), %rcx |
| ; NO512-NEXT: xorq 24(%rsi), %rcx |
| ; NO512-NEXT: xorq 40(%rsi), %rdx |
| ; NO512-NEXT: orq %rcx, %rax |
| ; NO512-NEXT: movq 104(%rdi), %rcx |
| ; NO512-NEXT: xorq 104(%rsi), %rcx |
| ; NO512-NEXT: orq %rdx, %rcx |
| ; NO512-NEXT: movq 72(%rdi), %rdx |
| ; NO512-NEXT: xorq 72(%rsi), %rdx |
| ; NO512-NEXT: orq %rdx, %rcx |
| ; NO512-NEXT: movq 16(%rdi), %r10 |
| ; NO512-NEXT: orq %rax, %rcx |
| ; NO512-NEXT: movq 8(%rdi), %rax |
| ; NO512-NEXT: xorq 8(%rsi), %rax |
| ; NO512-NEXT: xorq 48(%rsi), %r9 |
| ; NO512-NEXT: orq %rax, %rcx |
| ; NO512-NEXT: movq 112(%rdi), %rax |
| ; NO512-NEXT: xorq 112(%rsi), %rax |
| ; NO512-NEXT: orq %r9, %rax |
| ; NO512-NEXT: movq 80(%rdi), %rdx |
| ; NO512-NEXT: xorq 80(%rsi), %rdx |
| ; NO512-NEXT: orq %rdx, %rax |
| ; NO512-NEXT: movq (%rdi), %r9 |
| ; NO512-NEXT: xorq 16(%rsi), %r10 |
| ; NO512-NEXT: xorq (%rsi), %r9 |
| ; NO512-NEXT: xorq 32(%rsi), %r8 |
| ; NO512-NEXT: orq %r10, %rax |
| ; NO512-NEXT: movq 96(%rdi), %rdx |
| ; NO512-NEXT: movq 64(%rdi), %rdi |
| ; NO512-NEXT: xorq 64(%rsi), %rdi |
| ; NO512-NEXT: xorq 96(%rsi), %rdx |
| ; NO512-NEXT: orq %r8, %rdx |
| ; NO512-NEXT: orq %rdi, %rdx |
| ; NO512-NEXT: orq %rax, %rdx |
| ; NO512-NEXT: orq %r9, %rdx |
| ; NO512-NEXT: xorl %eax, %eax |
| ; NO512-NEXT: orq %rcx, %rdx |
| ; NO512-NEXT: sete %al |
| ; NO512-NEXT: retq |
| ; |
| ; AVX512F-LABEL: eq_i512_pair: |
| ; AVX512F: # %bb.0: |
| ; AVX512F-NEXT: vmovdqu64 (%rdi), %zmm0 |
| ; AVX512F-NEXT: vmovdqu64 64(%rdi), %zmm1 |
| ; AVX512F-NEXT: vpcmpneqd 64(%rsi), %zmm1, %k0 |
| ; AVX512F-NEXT: vpcmpneqd (%rsi), %zmm0, %k1 |
| ; AVX512F-NEXT: xorl %eax, %eax |
| ; AVX512F-NEXT: kortestw %k0, %k1 |
| ; AVX512F-NEXT: sete %al |
| ; AVX512F-NEXT: vzeroupper |
| ; AVX512F-NEXT: retq |
| ; |
| ; AVX512BW-LABEL: eq_i512_pair: |
| ; AVX512BW: # %bb.0: |
| ; AVX512BW-NEXT: vmovdqu64 (%rdi), %zmm0 |
| ; AVX512BW-NEXT: vmovdqu64 64(%rdi), %zmm1 |
| ; AVX512BW-NEXT: vpcmpneqb 64(%rsi), %zmm1, %k0 |
| ; AVX512BW-NEXT: vpcmpneqb (%rsi), %zmm0, %k1 |
| ; AVX512BW-NEXT: xorl %eax, %eax |
| ; AVX512BW-NEXT: kortestq %k0, %k1 |
| ; AVX512BW-NEXT: sete %al |
| ; AVX512BW-NEXT: vzeroupper |
| ; AVX512BW-NEXT: retq |
| %a0 = load i512, i512* %a |
| %b0 = load i512, i512* %b |
| %xor1 = xor i512 %a0, %b0 |
| %ap1 = getelementptr i512, i512* %a, i512 1 |
| %bp1 = getelementptr i512, i512* %b, i512 1 |
| %a1 = load i512, i512* %ap1 |
| %b1 = load i512, i512* %bp1 |
| %xor2 = xor i512 %a1, %b1 |
| %or = or i512 %xor1, %xor2 |
| %cmp = icmp eq i512 %or, 0 |
| %z = zext i1 %cmp to i32 |
| ret i32 %z |
| } |
| |
| ; PR41971: Comparison using vector types is not favorable here. |
| define i1 @eq_i128_args(i128 %a, i128 %b) { |
| ; ANY-LABEL: eq_i128_args: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: xorq %rcx, %rsi |
| ; ANY-NEXT: xorq %rdx, %rdi |
| ; ANY-NEXT: orq %rsi, %rdi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %r = icmp eq i128 %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i256_args(i256 %a, i256 %b) { |
| ; ANY-LABEL: eq_i256_args: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: xorq %r9, %rsi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rcx |
| ; ANY-NEXT: orq %rsi, %rcx |
| ; ANY-NEXT: xorq %r8, %rdi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdx |
| ; ANY-NEXT: orq %rdi, %rdx |
| ; ANY-NEXT: orq %rcx, %rdx |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %r = icmp eq i256 %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i512_args(i512 %a, i512 %b) { |
| ; ANY-LABEL: eq_i512_args: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: movq {{[0-9]+}}(%rsp), %r10 |
| ; ANY-NEXT: movq {{[0-9]+}}(%rsp), %rax |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rax |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rcx |
| ; ANY-NEXT: orq %rax, %rcx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r9 |
| ; ANY-NEXT: orq %rcx, %r9 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rsi |
| ; ANY-NEXT: orq %r9, %rsi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r10 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdx |
| ; ANY-NEXT: orq %r10, %rdx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r8 |
| ; ANY-NEXT: orq %rdx, %r8 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdi |
| ; ANY-NEXT: orq %r8, %rdi |
| ; ANY-NEXT: orq %rsi, %rdi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %r = icmp eq i512 %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i128_op(i128 %a, i128 %b) { |
| ; ANY-LABEL: eq_i128_op: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: addq $1, %rdi |
| ; ANY-NEXT: adcq $0, %rsi |
| ; ANY-NEXT: xorq %rdx, %rdi |
| ; ANY-NEXT: xorq %rcx, %rsi |
| ; ANY-NEXT: orq %rdi, %rsi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a2 = add i128 %a, 1 |
| %r = icmp eq i128 %a2, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i256_op(i256 %a, i256 %b) { |
| ; ANY-LABEL: eq_i256_op: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: addq $1, %rdi |
| ; ANY-NEXT: adcq $0, %rsi |
| ; ANY-NEXT: adcq $0, %rdx |
| ; ANY-NEXT: adcq $0, %rcx |
| ; ANY-NEXT: xorq %r8, %rdi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdx |
| ; ANY-NEXT: orq %rdi, %rdx |
| ; ANY-NEXT: xorq %r9, %rsi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rcx |
| ; ANY-NEXT: orq %rsi, %rcx |
| ; ANY-NEXT: orq %rdx, %rcx |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a2 = add i256 %a, 1 |
| %r = icmp eq i256 %a2, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i512_op(i512 %a, i512 %b) { |
| ; ANY-LABEL: eq_i512_op: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: movq {{[0-9]+}}(%rsp), %r10 |
| ; ANY-NEXT: movq {{[0-9]+}}(%rsp), %rax |
| ; ANY-NEXT: addq $1, %rdi |
| ; ANY-NEXT: adcq $0, %rsi |
| ; ANY-NEXT: adcq $0, %rdx |
| ; ANY-NEXT: adcq $0, %rcx |
| ; ANY-NEXT: adcq $0, %r8 |
| ; ANY-NEXT: adcq $0, %r9 |
| ; ANY-NEXT: adcq $0, %r10 |
| ; ANY-NEXT: adcq $0, %rax |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rsi |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r9 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rcx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rax |
| ; ANY-NEXT: orq %rcx, %rax |
| ; ANY-NEXT: orq %r9, %rax |
| ; ANY-NEXT: orq %rsi, %rax |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r10 |
| ; ANY-NEXT: orq %rdx, %r10 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r8 |
| ; ANY-NEXT: orq %r10, %r8 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rdi |
| ; ANY-NEXT: orq %r8, %rdi |
| ; ANY-NEXT: orq %rax, %rdi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a2 = add i512 %a, 1 |
| %r = icmp eq i512 %a2, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i128_load_arg(i128 *%p, i128 %b) { |
| ; ANY-LABEL: eq_i128_load_arg: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: xorq 8(%rdi), %rdx |
| ; ANY-NEXT: xorq (%rdi), %rsi |
| ; ANY-NEXT: orq %rdx, %rsi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a = load i128, i128* %p |
| %r = icmp eq i128 %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i256_load_arg(i256 *%p, i256 %b) { |
| ; ANY-LABEL: eq_i256_load_arg: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: xorq 24(%rdi), %r8 |
| ; ANY-NEXT: xorq 8(%rdi), %rdx |
| ; ANY-NEXT: orq %r8, %rdx |
| ; ANY-NEXT: xorq 16(%rdi), %rcx |
| ; ANY-NEXT: xorq (%rdi), %rsi |
| ; ANY-NEXT: orq %rcx, %rsi |
| ; ANY-NEXT: orq %rdx, %rsi |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a = load i256, i256* %p |
| %r = icmp eq i256 %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @eq_i512_load_arg(i512 *%p, i512 %b) { |
| ; ANY-LABEL: eq_i512_load_arg: |
| ; ANY: # %bb.0: |
| ; ANY-NEXT: movq 40(%rdi), %r10 |
| ; ANY-NEXT: movq 48(%rdi), %rax |
| ; ANY-NEXT: movq 56(%rdi), %r11 |
| ; ANY-NEXT: xorq 24(%rdi), %r8 |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r11 |
| ; ANY-NEXT: orq %r8, %r11 |
| ; ANY-NEXT: xorq 8(%rdi), %rdx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %r10 |
| ; ANY-NEXT: orq %r11, %r10 |
| ; ANY-NEXT: orq %rdx, %r10 |
| ; ANY-NEXT: xorq 32(%rdi), %r9 |
| ; ANY-NEXT: xorq (%rdi), %rsi |
| ; ANY-NEXT: xorq 16(%rdi), %rcx |
| ; ANY-NEXT: xorq {{[0-9]+}}(%rsp), %rax |
| ; ANY-NEXT: orq %rcx, %rax |
| ; ANY-NEXT: orq %r9, %rax |
| ; ANY-NEXT: orq %rsi, %rax |
| ; ANY-NEXT: orq %r10, %rax |
| ; ANY-NEXT: sete %al |
| ; ANY-NEXT: retq |
| %a = load i512, i512* %p |
| %r = icmp eq i512 %a, %b |
| ret i1 %r |
| } |