
When we first began (2015) to lower f32/f64 selects to X86ISD::BLENDV(scalar_to_vector(),scalar_to_vector(),scalar_to_vector()), we limited it to AVX targets to avoid issues with SSE41's xmm0 constraint for the condition mask. Since then we've seen general improvements in TwoAddressInstruction and better handling of condition commutation for X86ISD::BLENDV nodes, which should address many of the original concerns of using SSE41 BLENDVPD/S. In most cases we will replace 3 logic instruction with the BLENDV node and (up to 3) additional moves. Although the BLENDV is often more expensive on original SSE41 targets, this should still be an improvement in a majority of cases. We also have no equivalent restrictions for SSE41 for v2f64/v4f32 vector selection. Fixes #105807
214 lines
6.1 KiB
LLVM
214 lines
6.1 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 | FileCheck %s
|
|
|
|
define double @test1(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltsd %xmm2, %xmm0
|
|
; CHECK-NEXT: andpd %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp olt double %a, %eps
|
|
%cond = select i1 %cmp, double %b, double 0.000000e+00
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test2(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmplesd %xmm2, %xmm0
|
|
; CHECK-NEXT: andpd %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ole double %a, %eps
|
|
%cond = select i1 %cmp, double %b, double 0.000000e+00
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test3(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test3:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltsd %xmm0, %xmm2
|
|
; CHECK-NEXT: andpd %xmm1, %xmm2
|
|
; CHECK-NEXT: movapd %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ogt double %a, %eps
|
|
%cond = select i1 %cmp, double %b, double 0.000000e+00
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test4(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test4:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmplesd %xmm0, %xmm2
|
|
; CHECK-NEXT: andpd %xmm1, %xmm2
|
|
; CHECK-NEXT: movapd %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge double %a, %eps
|
|
%cond = select i1 %cmp, double %b, double 0.000000e+00
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test5(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test5:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltsd %xmm2, %xmm0
|
|
; CHECK-NEXT: andnpd %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp olt double %a, %eps
|
|
%cond = select i1 %cmp, double 0.000000e+00, double %b
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test6(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test6:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmplesd %xmm2, %xmm0
|
|
; CHECK-NEXT: andnpd %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ole double %a, %eps
|
|
%cond = select i1 %cmp, double 0.000000e+00, double %b
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test7(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test7:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltsd %xmm0, %xmm2
|
|
; CHECK-NEXT: andnpd %xmm1, %xmm2
|
|
; CHECK-NEXT: movapd %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ogt double %a, %eps
|
|
%cond = select i1 %cmp, double 0.000000e+00, double %b
|
|
ret double %cond
|
|
}
|
|
|
|
define double @test8(double %a, double %b, double %eps) {
|
|
; CHECK-LABEL: test8:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmplesd %xmm0, %xmm2
|
|
; CHECK-NEXT: andnpd %xmm1, %xmm2
|
|
; CHECK-NEXT: movapd %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge double %a, %eps
|
|
%cond = select i1 %cmp, double 0.000000e+00, double %b
|
|
ret double %cond
|
|
}
|
|
|
|
define float @test9(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test9:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltss %xmm2, %xmm0
|
|
; CHECK-NEXT: andps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp olt float %a, %eps
|
|
%cond = select i1 %cmp, float %b, float 0.000000e+00
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test10(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test10:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpless %xmm2, %xmm0
|
|
; CHECK-NEXT: andps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ole float %a, %eps
|
|
%cond = select i1 %cmp, float %b, float 0.000000e+00
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test11(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test11:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltss %xmm0, %xmm2
|
|
; CHECK-NEXT: andps %xmm1, %xmm2
|
|
; CHECK-NEXT: movaps %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ogt float %a, %eps
|
|
%cond = select i1 %cmp, float %b, float 0.000000e+00
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test12(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test12:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpless %xmm0, %xmm2
|
|
; CHECK-NEXT: andps %xmm1, %xmm2
|
|
; CHECK-NEXT: movaps %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge float %a, %eps
|
|
%cond = select i1 %cmp, float %b, float 0.000000e+00
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test13(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test13:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltss %xmm2, %xmm0
|
|
; CHECK-NEXT: andnps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp olt float %a, %eps
|
|
%cond = select i1 %cmp, float 0.000000e+00, float %b
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test14(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test14:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpless %xmm2, %xmm0
|
|
; CHECK-NEXT: andnps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ole float %a, %eps
|
|
%cond = select i1 %cmp, float 0.000000e+00, float %b
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test15(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test15:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpltss %xmm0, %xmm2
|
|
; CHECK-NEXT: andnps %xmm1, %xmm2
|
|
; CHECK-NEXT: movaps %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp ogt float %a, %eps
|
|
%cond = select i1 %cmp, float 0.000000e+00, float %b
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test16(float %a, float %b, float %eps) {
|
|
; CHECK-LABEL: test16:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpless %xmm0, %xmm2
|
|
; CHECK-NEXT: andnps %xmm1, %xmm2
|
|
; CHECK-NEXT: movaps %xmm2, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge float %a, %eps
|
|
%cond = select i1 %cmp, float 0.000000e+00, float %b
|
|
ret float %cond
|
|
}
|
|
|
|
define float @test17(float %a, float %b, float %c, float %eps) {
|
|
; CHECK-LABEL: test17:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmpless %xmm0, %xmm3
|
|
; CHECK-NEXT: movaps %xmm3, %xmm0
|
|
; CHECK-NEXT: blendvps %xmm0, %xmm2, %xmm1
|
|
; CHECK-NEXT: movaps %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge float %a, %eps
|
|
%cond = select i1 %cmp, float %c, float %b
|
|
ret float %cond
|
|
}
|
|
|
|
define double @test18(double %a, double %b, double %c, double %eps) {
|
|
; CHECK-LABEL: test18:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: cmplesd %xmm0, %xmm3
|
|
; CHECK-NEXT: movapd %xmm3, %xmm0
|
|
; CHECK-NEXT: blendvpd %xmm0, %xmm2, %xmm1
|
|
; CHECK-NEXT: movapd %xmm1, %xmm0
|
|
; CHECK-NEXT: retq
|
|
%cmp = fcmp oge double %a, %eps
|
|
%cond = select i1 %cmp, double %c, double %b
|
|
ret double %cond
|
|
}
|
|
|