AVX-512: DAG lowering for scalar MIN/MAX commutable ops

DAG lowering was missing for the scalar FMINC, FMAXC nodes.
The nodes are generated only in the "unsafe-fp-math" mode.
Added tests.

llvm-svn: 275048
This commit is contained in:
Elena Demikhovsky 2016-07-11 06:08:06 +00:00
parent f580dd98cb
commit d84f337953
2 changed files with 72 additions and 3 deletions

View File

@ -3770,7 +3770,7 @@ multiclass avx512_fp_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
(ins _.FRC:$src1, _.ScalarMemOp:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set _.FRC:$dst, (OpNode _.FRC:$src1,
(_.ScalarLdFrag addr:$src2)))], itins.rr>;
(_.ScalarLdFrag addr:$src2)))], itins.rm>;
}
}
@ -3827,8 +3827,41 @@ defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnd, SSE_ALU_ITINS_S
defm VMUL : avx512_binop_s_round<0x59, "vmul", fmul, X86fmulRnd, SSE_ALU_ITINS_S, 1>;
defm VSUB : avx512_binop_s_round<0x5C, "vsub", fsub, X86fsubRnd, SSE_ALU_ITINS_S, 0>;
defm VDIV : avx512_binop_s_round<0x5E, "vdiv", fdiv, X86fdivRnd, SSE_ALU_ITINS_S, 0>;
defm VMIN : avx512_binop_s_sae <0x5D, "vmin", X86fmin, X86fminRnd, SSE_ALU_ITINS_S, 1>;
defm VMAX : avx512_binop_s_sae <0x5F, "vmax", X86fmax, X86fmaxRnd, SSE_ALU_ITINS_S, 1>;
defm VMIN : avx512_binop_s_sae <0x5D, "vmin", X86fmin, X86fminRnd, SSE_ALU_ITINS_S, 0>;
defm VMAX : avx512_binop_s_sae <0x5F, "vmax", X86fmax, X86fmaxRnd, SSE_ALU_ITINS_S, 0>;
// MIN/MAX nodes are commutable under "unsafe-fp-math". In this case we use
// X86fminc and X86fmaxc instead of X86fmin and X86fmax
multiclass avx512_comutable_binop_s<bits<8> opc, string OpcodeStr,
X86VectorVTInfo _, SDNode OpNode, OpndItins itins> {
let isCodeGenOnly = 1, isCommutable =1, Predicates = [HasAVX512] in {
def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
(ins _.FRC:$src1, _.FRC:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
itins.rr>;
def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
(ins _.FRC:$src1, _.ScalarMemOp:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set _.FRC:$dst, (OpNode _.FRC:$src1,
(_.ScalarLdFrag addr:$src2)))], itins.rm>;
}
}
defm VMINCSSZ : avx512_comutable_binop_s<0x5D, "vminss", f32x_info, X86fminc,
SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
EVEX_CD8<32, CD8VT1>;
defm VMINCSDZ : avx512_comutable_binop_s<0x5D, "vminsd", f64x_info, X86fminc,
SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
EVEX_CD8<64, CD8VT1>;
defm VMAXCSSZ : avx512_comutable_binop_s<0x5F, "vmaxss", f32x_info, X86fmaxc,
SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
EVEX_CD8<32, CD8VT1>;
defm VMAXCSDZ : avx512_comutable_binop_s<0x5F, "vmaxsd", f64x_info, X86fmaxc,
SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
EVEX_CD8<64, CD8VT1>;
multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
X86VectorVTInfo _, bit IsCommutable> {

View File

@ -69,3 +69,39 @@ define <8 x double> @test_min_v8f64(<8 x double>* %a_ptr, <8 x double> %b) {
%tmp4 = select <8 x i1> %tmp, <8 x double> %a, <8 x double> %b
ret <8 x double> %tmp4;
}
define float @test_min_f32(float %a, float* %ptr) {
; CHECK_UNSAFE-LABEL: test_min_f32:
; CHECK_UNSAFE: # BB#0: # %entry
; CHECK_UNSAFE-NEXT: vminss (%rdi), %xmm0, %xmm0
; CHECK_UNSAFE-NEXT: retq
;
; CHECK-LABEL: test_min_f32:
; CHECK: # BB#0: # %entry
; CHECK-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
; CHECK-NEXT: vminss %xmm0, %xmm1, %xmm0
; CHECK-NEXT: retq
entry:
%0 = load float, float* %ptr
%1 = fcmp fast olt float %0, %a
%2 = select i1 %1, float %0, float %a
ret float %2
}
define double @test_max_f64(double %a, double* %ptr) {
; CHECK_UNSAFE-LABEL: test_max_f64:
; CHECK_UNSAFE: # BB#0: # %entry
; CHECK_UNSAFE-NEXT: vmaxsd (%rdi), %xmm0, %xmm0
; CHECK_UNSAFE-NEXT: retq
;
; CHECK-LABEL: test_max_f64:
; CHECK: # BB#0: # %entry
; CHECK-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero
; CHECK-NEXT: vmaxsd %xmm0, %xmm1, %xmm0
; CHECK-NEXT: retq
entry:
%0 = load double, double* %ptr
%1 = fcmp fast ogt double %0, %a
%2 = select i1 %1, double %0, double %a
ret double %2
}