Files
clang-p2996/llvm/test/CodeGen/X86/setcc-combine.ll
Simon Pilgrim a2a0089ac3 [X86] movsd/movss/movd/movq - add support for constant comments (#78601)
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.
2024-01-19 14:21:26 +00:00

1018 lines
29 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse2 < %s | FileCheck %s --check-prefixes=CHECK,SSE2
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 < %s | FileCheck %s --check-prefixes=CHECK,SSE41
define i32 @test_eq_1(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_eq_1:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: notl %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_eq_1:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm0, %xmm1
; SSE41-NEXT: pextrd $1, %xmm1, %eax
; SSE41-NEXT: notl %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp eq <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_ne_1(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_ne_1:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_ne_1:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm0, %xmm1
; SSE41-NEXT: pextrd $1, %xmm1, %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp ne <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_le_1(<4 x i32> %A, <4 x i32> %B) {
; CHECK-LABEL: test_le_1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $-1, %eax
; CHECK-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sle <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_ge_1(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_ge_1:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: notl %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_ge_1:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm0, %xmm1
; SSE41-NEXT: pextrd $1, %xmm1, %eax
; SSE41-NEXT: notl %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sge <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_lt_1(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_lt_1:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_lt_1:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm0, %xmm1
; SSE41-NEXT: pextrd $1, %xmm1, %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp slt <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_gt_1(<4 x i32> %A, <4 x i32> %B) {
; CHECK-LABEL: test_gt_1:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retq
%cmp = icmp slt <4 x i32> %A, %B
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sgt <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_eq_2(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_eq_2:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: notl %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_eq_2:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm1, %xmm0
; SSE41-NEXT: pextrd $1, %xmm0, %eax
; SSE41-NEXT: notl %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp eq <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_ne_2(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_ne_2:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_ne_2:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm1, %xmm0
; SSE41-NEXT: pextrd $1, %xmm0, %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp ne <4 x i32> %sext, zeroinitializer
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_le_2(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_le_2:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: notl %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_le_2:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm1, %xmm0
; SSE41-NEXT: pextrd $1, %xmm0, %eax
; SSE41-NEXT: notl %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sle <4 x i32> zeroinitializer, %sext
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_ge_2(<4 x i32> %A, <4 x i32> %B) {
; CHECK-LABEL: test_ge_2:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $-1, %eax
; CHECK-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sge <4 x i32> zeroinitializer, %sext
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_lt_2(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_lt_2:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_lt_2:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm1, %xmm0
; SSE41-NEXT: pextrd $1, %xmm0, %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp slt <4 x i32> zeroinitializer, %sext
%t0 = extractelement <4 x i1> %cmp, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
define i32 @test_gt_2(<4 x i32> %A, <4 x i32> %B) {
; SSE2-LABEL: test_gt_2:
; SSE2: # %bb.0:
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE41-LABEL: test_gt_2:
; SSE41: # %bb.0:
; SSE41-NEXT: pcmpgtd %xmm1, %xmm0
; SSE41-NEXT: pextrd $1, %xmm0, %eax
; SSE41-NEXT: retq
%cmp = icmp slt <4 x i32> %B, %A
%sext = sext <4 x i1> %cmp to <4 x i32>
%cmp1 = icmp sgt <4 x i32> zeroinitializer, %sext
%t0 = extractelement <4 x i1> %cmp1, i32 1
%t1 = sext i1 %t0 to i32
ret i32 %t1
}
; (and (setne X, 0), (setne X, -1)) --> (setuge (add X, 1), 2)
; Don't combine with i1 - out of range constant
define void @test_i1_uge(ptr%A2) {
; CHECK-LABEL: test_i1_uge:
; CHECK: # %bb.0:
; CHECK-NEXT: movzbl (%rdi), %eax
; CHECK-NEXT: notb %al
; CHECK-NEXT: andb $1, %al
; CHECK-NEXT: movb %al, (%rdi)
; CHECK-NEXT: retq
%L5 = load i1, ptr %A2
%C3 = icmp ne i1 %L5, true
%C8 = icmp eq i1 %L5, false
%C9 = icmp ugt i1 %C3, %C8
%G3 = getelementptr i1, ptr %A2, i1 %C9
store i1 %C3, ptr %G3
ret void
}
; This should not get folded to 0.
define i64 @PR40657(i8 %var2, i8 %var9) {
; CHECK-LABEL: PR40657:
; CHECK: # %bb.0:
; CHECK-NEXT: addb %sil, %dil
; CHECK-NEXT: incb %dil
; CHECK-NEXT: movzbl %dil, %eax
; CHECK-NEXT: andl $1, %eax
; CHECK-NEXT: retq
%var6 = trunc i8 %var9 to i1
%var7 = trunc i8 175 to i1
%var3 = sub nsw i1 %var6, %var7
%var4 = icmp eq i64 1114591064, 1114591064
%var1 = udiv i1 %var3, %var4
%var0 = trunc i8 %var2 to i1
%res = sub nsw nuw i1 %var0, %var1
%res.cast = zext i1 %res to i64
ret i64 %res.cast
}
; This should not get folded to 0.
define i64 @PR40657_commute(i8 %var7, i8 %var8, i8 %var9) {
; CHECK-LABEL: PR40657_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: subb %dil, %sil
; CHECK-NEXT: subb %sil, %dl
; CHECK-NEXT: subb %dl, %sil
; CHECK-NEXT: xorb %dl, %sil
; CHECK-NEXT: subb %sil, %dl
; CHECK-NEXT: movzbl %dl, %eax
; CHECK-NEXT: andl $1, %eax
; CHECK-NEXT: retq
%var4 = trunc i8 %var9 to i1
%var5 = trunc i8 %var8 to i1
%var6 = trunc i8 %var7 to i1
%var3 = sub nsw nuw i1 %var5, %var6
%var0 = sub nuw i1 %var4, %var3
%var2 = sub i1 %var3, %var0
%var1 = icmp ne i1 %var0, %var2
%res = sub nsw nuw i1 %var0, %var1
%res.cast = zext i1 %res to i64
ret i64 %res.cast
}
define i64 @sub_to_shift_to_add(i32 %x, i32 %y, i64 %s1, i64 %s2) {
; CHECK-LABEL: sub_to_shift_to_add:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: addl %esi, %esi
; CHECK-NEXT: cmpl %esi, %edi
; CHECK-NEXT: cmovneq %rcx, %rax
; CHECK-NEXT: retq
%sub = sub i32 %x, %y
%cmp = icmp eq i32 %sub, %y
%r = select i1 %cmp, i64 %s1, i64 %s2
ret i64 %r
}
define <4 x float> @sub_to_shift_to_add_vec(<4 x i32> %x, <4 x i32> %y, <4 x float> %s1, <4 x float> %s2) {
; SSE2-LABEL: sub_to_shift_to_add_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: paddd %xmm1, %xmm1
; SSE2-NEXT: pcmpeqd %xmm1, %xmm0
; SSE2-NEXT: pand %xmm0, %xmm2
; SSE2-NEXT: pandn %xmm3, %xmm0
; SSE2-NEXT: por %xmm2, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: sub_to_shift_to_add_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: paddd %xmm1, %xmm1
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: blendvps %xmm0, %xmm2, %xmm3
; SSE41-NEXT: movaps %xmm3, %xmm0
; SSE41-NEXT: retq
%sub = sub <4 x i32> %x, %y
%cmp = icmp eq <4 x i32> %sub, %y
%r = select <4 x i1> %cmp, <4 x float> %s1, <4 x float> %s2
ret <4 x float> %r
}
define i64 @sub_constant_to_shift_to_add(i32 %x, i64 %s1, i64 %s2) {
; CHECK-LABEL: sub_constant_to_shift_to_add:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rsi, %rax
; CHECK-NEXT: addl %edi, %edi
; CHECK-NEXT: cmpl $42, %edi
; CHECK-NEXT: cmovneq %rdx, %rax
; CHECK-NEXT: retq
%sub = sub i32 42, %x
%cmp = icmp eq i32 %sub, %x
%r = select i1 %cmp, i64 %s1, i64 %s2
ret i64 %r
}
define float @olt(float %x) {
; CHECK-LABEL: olt:
; CHECK: # %bb.0:
; CHECK-NEXT: movaps {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorps %xmm0, %xmm1
; CHECK-NEXT: minss %xmm1, %xmm0
; CHECK-NEXT: retq
%cmp = fcmp olt float %x, 0.0
%neg = fneg float %x
%r = select i1 %cmp, float %x, float %neg
ret float %r
}
define double @ogt(double %x) {
; CHECK-LABEL: ogt:
; CHECK: # %bb.0:
; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorpd %xmm0, %xmm1
; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: retq
%neg = fneg double %x
%cmp = fcmp ogt double %x, 0.0
%r = select i1 %cmp, double %x, double %neg
ret double %r
}
define <4 x float> @olt_swap(<4 x float> %x) {
; CHECK-LABEL: olt_swap:
; CHECK: # %bb.0:
; CHECK-NEXT: movaps {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorps %xmm0, %xmm1
; CHECK-NEXT: maxps %xmm0, %xmm1
; CHECK-NEXT: movaps %xmm1, %xmm0
; CHECK-NEXT: retq
%cmp = fcmp olt <4 x float> %x, zeroinitializer
%neg = fneg <4 x float> %x
%r = select <4 x i1> %cmp, <4 x float> %neg, <4 x float> %x
ret <4 x float> %r
}
define <2 x double> @ogt_swap(<2 x double> %x) {
; CHECK-LABEL: ogt_swap:
; CHECK: # %bb.0:
; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorpd %xmm0, %xmm1
; CHECK-NEXT: minpd %xmm0, %xmm1
; CHECK-NEXT: movapd %xmm1, %xmm0
; CHECK-NEXT: retq
%neg = fneg <2 x double> %x
%cmp = fcmp ogt <2 x double> %x, zeroinitializer
%r = select <2 x i1> %cmp, <2 x double> %neg, <2 x double> %x
ret <2 x double> %r
}
define <4 x float> @ole(<4 x float> %x) {
; SSE2-LABEL: ole:
; SSE2: # %bb.0:
; SSE2-NEXT: movaps {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
; SSE2-NEXT: xorps %xmm0, %xmm2
; SSE2-NEXT: movaps %xmm0, %xmm1
; SSE2-NEXT: cmpleps %xmm2, %xmm1
; SSE2-NEXT: andps %xmm1, %xmm2
; SSE2-NEXT: andnps %xmm0, %xmm1
; SSE2-NEXT: orps %xmm2, %xmm1
; SSE2-NEXT: movaps %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: ole:
; SSE41: # %bb.0:
; SSE41-NEXT: movaps %xmm0, %xmm1
; SSE41-NEXT: movaps {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
; SSE41-NEXT: xorps %xmm0, %xmm2
; SSE41-NEXT: cmpleps %xmm2, %xmm0
; SSE41-NEXT: blendvps %xmm0, %xmm2, %xmm1
; SSE41-NEXT: movaps %xmm1, %xmm0
; SSE41-NEXT: retq
%cmp = fcmp ole <4 x float> %x, zeroinitializer
%neg = fneg <4 x float> %x
%r = select <4 x i1> %cmp, <4 x float> %neg, <4 x float> %x
ret <4 x float> %r
}
define <2 x double> @oge(<2 x double> %x) {
; SSE2-LABEL: oge:
; SSE2: # %bb.0:
; SSE2-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
; SSE2-NEXT: xorpd %xmm0, %xmm2
; SSE2-NEXT: movapd %xmm2, %xmm1
; SSE2-NEXT: cmplepd %xmm0, %xmm1
; SSE2-NEXT: andpd %xmm1, %xmm2
; SSE2-NEXT: andnpd %xmm0, %xmm1
; SSE2-NEXT: orpd %xmm2, %xmm1
; SSE2-NEXT: movapd %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: oge:
; SSE41: # %bb.0:
; SSE41-NEXT: movapd %xmm0, %xmm1
; SSE41-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
; SSE41-NEXT: xorpd %xmm0, %xmm2
; SSE41-NEXT: movapd %xmm2, %xmm0
; SSE41-NEXT: cmplepd %xmm1, %xmm0
; SSE41-NEXT: blendvpd %xmm0, %xmm2, %xmm1
; SSE41-NEXT: movapd %xmm1, %xmm0
; SSE41-NEXT: retq
%neg = fneg <2 x double> %x
%cmp = fcmp oge <2 x double> %x, zeroinitializer
%r = select <2 x i1> %cmp, <2 x double> %neg, <2 x double> %x
ret <2 x double> %r
}
; negative test - don't create an fneg to replace 0.0 operand
define double @ogt_no_fneg(double %x, double %y) {
; CHECK-LABEL: ogt_no_fneg:
; CHECK: # %bb.0:
; CHECK-NEXT: xorpd %xmm2, %xmm2
; CHECK-NEXT: cmpltsd %xmm0, %xmm2
; CHECK-NEXT: andpd %xmm2, %xmm0
; CHECK-NEXT: andnpd %xmm1, %xmm2
; CHECK-NEXT: orpd %xmm2, %xmm0
; CHECK-NEXT: retq
%cmp = fcmp ogt double %x, 0.0
%r = select i1 %cmp, double %x, double %y
ret double %r
}
; negative test - can't change the setcc for non-zero constant
define double @ogt_no_zero(double %x) {
; CHECK-LABEL: ogt_no_zero:
; CHECK: # %bb.0:
; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorpd %xmm0, %xmm1
; CHECK-NEXT: movsd {{.*#+}} xmm2 = [1.0E+0,0.0E+0]
; CHECK-NEXT: cmpltsd %xmm0, %xmm2
; CHECK-NEXT: andpd %xmm2, %xmm0
; CHECK-NEXT: andnpd %xmm1, %xmm2
; CHECK-NEXT: orpd %xmm2, %xmm0
; CHECK-NEXT: retq
%neg = fneg double %x
%cmp = fcmp ogt double %x, 1.0
%r = select i1 %cmp, double %x, double %neg
ret double %r
}
define i64 @cmp_sgt_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_sgt_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rdi, %rsi
; CHECK-NEXT: setg %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp sgt i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_sgt_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_sgt_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: setl %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp sgt i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_sgt_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: cmp_sgt_not_with_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: pcmpgtd %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp sgt <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_ugt_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_ugt_not:
; CHECK: # %bb.0:
; CHECK-NEXT: notq %rdi
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq %rsi, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp ugt i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_ugt_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_ugt_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp ugt i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_ugt_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; SSE2-LABEL: cmp_ugt_not_with_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: pxor %xmm1, %xmm2
; SSE2-NEXT: pcmpgtd %xmm0, %xmm2
; SSE2-NEXT: movdqa %xmm2, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: cmp_ugt_not_with_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: pminud %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm1
; SSE41-NEXT: pxor %xmm1, %xmm0
; SSE41-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp ugt <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_sge_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_sge_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rdi, %rsi
; CHECK-NEXT: setge %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp sge i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_sge_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_sge_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-42, %rdi
; CHECK-NEXT: setl %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp sge i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_sge_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; SSE2-LABEL: cmp_sge_not_with_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
; SSE2-NEXT: pxor %xmm2, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pcmpeqd %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: cmp_sge_not_with_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: pmaxud %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp uge <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_uge_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_uge_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rdi, %rsi
; CHECK-NEXT: adcq $-1, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp uge i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_uge_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_uge_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-42, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp uge i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_uge_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; SSE2-LABEL: cmp_uge_not_with_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
; SSE2-NEXT: pxor %xmm2, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: pcmpeqd %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: cmp_uge_not_with_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: pmaxud %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp uge <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_sle_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_sle_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rdi, %rsi
; CHECK-NEXT: setle %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp sle i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_sle_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_sle_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: setge %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp sle i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_sle_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: cmp_sle_not_with_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: pcmpgtd %xmm0, %xmm1
; CHECK-NEXT: pcmpeqd %xmm0, %xmm0
; CHECK-NEXT: pxor %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp sle <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_slt_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_slt_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rdi, %rsi
; CHECK-NEXT: setl %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp slt i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_slt_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_slt_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-42, %rdi
; CHECK-NEXT: setge %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp slt i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_slt_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: cmp_slt_not_with_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: pcmpgtd %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp slt <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_ult_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_ult_not:
; CHECK: # %bb.0:
; CHECK-NEXT: notq %rsi
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq %rdi, %rsi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp ult i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_ult_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_ult_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq $42, %rdi
; CHECK-NEXT: sbbq %rax, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp ult i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_ult_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; SSE2-LABEL: cmp_ult_not_with_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
; SSE2-NEXT: pxor %xmm2, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: pcmpgtd %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: cmp_ult_not_with_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: pmaxud %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm1
; SSE41-NEXT: pxor %xmm1, %xmm0
; SSE41-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp ult <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_ule_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_ule_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rsi, %rdi
; CHECK-NEXT: adcq $-1, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp ule i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_ule_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_ule_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: adcq $-1, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp ule i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_ule_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; SSE2-LABEL: cmp_ule_not_with_vec:
; SSE2: # %bb.0:
; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: pxor %xmm1, %xmm2
; SSE2-NEXT: pcmpgtd %xmm0, %xmm2
; SSE2-NEXT: pcmpeqd %xmm0, %xmm0
; SSE2-NEXT: pxor %xmm2, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: cmp_ule_not_with_vec:
; SSE41: # %bb.0:
; SSE41-NEXT: pminud %xmm1, %xmm0
; SSE41-NEXT: pcmpeqd %xmm1, %xmm0
; SSE41-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp ule <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_eq_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_eq_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rsi, %rdi
; CHECK-NEXT: sete %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp eq i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_eq_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_eq_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: sete %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp eq i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_eq_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: cmp_eq_not_with_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp eq <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_ne_not(i64 %a, i64 %b) {
; CHECK-LABEL: cmp_ne_not:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rsi, %rdi
; CHECK-NEXT: setne %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp ne i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_ne_not_with_constant(i64 %a) {
; CHECK-LABEL: cmp_ne_not_with_constant:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $-43, %rdi
; CHECK-NEXT: setne %al
; CHECK-NEXT: negq %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp ne i64 %na, 42
%r = sext i1 %c to i64
ret i64 %r
}
define <4 x i32> @cmp_ne_not_with_vec(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: cmp_ne_not_with_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
; CHECK-NEXT: pcmpeqd %xmm1, %xmm1
; CHECK-NEXT: pxor %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%nb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%c = icmp ne <4 x i32> %na, %nb
%r = sext <4 x i1> %c to <4 x i32>
ret <4 x i32> %r
}
define i64 @cmp_uge_not_commute(i64 %b, i64 %a) {
; CHECK-LABEL: cmp_uge_not_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rsi, %rdi
; CHECK-NEXT: adcq $-1, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%nb = xor i64 %b, -1
%c = icmp uge i64 %na, %nb
%r = sext i1 %c to i64
ret i64 %r
}
define i64 @cmp_ult_not_with_constant_commute(i64 %a) {
; CHECK-LABEL: cmp_ult_not_with_constant_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq $43, %rdi
; CHECK-NEXT: adcq $-1, %rax
; CHECK-NEXT: retq
%na = xor i64 %a, -1
%c = icmp ult i64 42, %a
%r = sext i1 %c to i64
ret i64 %r
}
define <2 x i64> @cmp_uge_not_with_vec2xi64(<2 x i64> %a, <2 x i64> %b) {
; CHECK-LABEL: cmp_uge_not_with_vec2xi64:
; CHECK: # %bb.0:
; CHECK-NEXT: movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
; CHECK-NEXT: pxor %xmm2, %xmm1
; CHECK-NEXT: pxor %xmm2, %xmm0
; CHECK-NEXT: movdqa %xmm0, %xmm2
; CHECK-NEXT: pcmpgtd %xmm1, %xmm2
; CHECK-NEXT: pshufd {{.*#+}} xmm3 = xmm2[0,0,2,2]
; CHECK-NEXT: pcmpeqd %xmm1, %xmm0
; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
; CHECK-NEXT: pand %xmm3, %xmm0
; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,1,3,3]
; CHECK-NEXT: por %xmm0, %xmm1
; CHECK-NEXT: pcmpeqd %xmm0, %xmm0
; CHECK-NEXT: pxor %xmm1, %xmm0
; CHECK-NEXT: retq
%na = xor <2 x i64> %a, <i64 -1, i64 -1>
%nb = xor <2 x i64> %b, <i64 -1, i64 -1>
%c = icmp uge <2 x i64> %na, %nb
%r = sext <2 x i1> %c to <2 x i64>
ret <2 x i64> %r
}