forked from OSchip/llvm-project
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:
parent
f580dd98cb
commit
d84f337953
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue