[llvm] r230891 - AVX-512: Added mask and rounding mode for scalar arithmetics

Elena Demikhovsky elena.demikhovsky at intel.com
Sat Feb 28 23:44:04 PST 2015


Author: delena
Date: Sun Mar  1 01:44:04 2015
New Revision: 230891

URL: http://llvm.org/viewvc/llvm-project?rev=230891&view=rev
Log:
AVX-512: Added mask and rounding mode for scalar arithmetics
Added more tests for scalar instructions to destinguish between AVX and AVX-512 forms.


Added:
    llvm/trunk/test/CodeGen/X86/avx512-scalar.ll
Modified:
    llvm/trunk/lib/Target/X86/X86InstrAVX512.td
    llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td
    llvm/trunk/lib/Target/X86/X86InstrSSE.td
    llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp

Modified: llvm/trunk/lib/Target/X86/X86InstrAVX512.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrAVX512.td?rev=230891&r1=230890&r2=230891&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrAVX512.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrAVX512.td Sun Mar  1 01:44:04 2015
@@ -3243,27 +3243,94 @@ defm VPANDN : avx512_binop_rm_vl_dq<0xDF
 //===----------------------------------------------------------------------===//
 // AVX-512  FP arithmetic
 //===----------------------------------------------------------------------===//
+multiclass avx512_fp_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
+                         SDNode OpNode, SDNode VecNode, OpndItins itins,
+                         bit IsCommutable> {
 
-multiclass avx512_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
-                                  SizeItins itins> {
-  defm SSZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"), OpNode, FR32X,
-                             f32mem, itins.s, 0>, XS, EVEX_4V, VEX_LIG,
-                             EVEX_CD8<32, CD8VT1>;
-  defm SDZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"), OpNode, FR64X,
-                             f64mem, itins.d, 0>, XD, VEX_W, EVEX_4V, VEX_LIG,
-                             EVEX_CD8<64, CD8VT1>;
+  defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
+                           (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
+                           "$src2, $src1", "$src1, $src2",
+                           (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
+                           (i32 FROUND_CURRENT)),
+                           "", itins.rr, IsCommutable>;
+
+  defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
+                         (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
+                         "$src2, $src1", "$src1, $src2",
+                         (VecNode (_.VT _.RC:$src1),
+                          (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
+                           (i32 FROUND_CURRENT)),
+                         "", itins.rm, IsCommutable>;
+  let isCodeGenOnly = 1, isCommutable = IsCommutable,
+      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.rr>;
+  }
+}
+
+multiclass avx512_fp_scalar_round<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
+                         SDNode VecNode, OpndItins itins, bit IsCommutable> {
+
+  defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
+                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
+                          "$rc, $src2, $src1", "$src1, $src2, $rc",
+                          (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
+                          (i32 imm:$rc)), "", itins.rr, IsCommutable>,
+                          EVEX_B, EVEX_RC;
 }
+multiclass avx512_fp_scalar_sae<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
+                         SDNode VecNode, OpndItins itins, bit IsCommutable> {
 
-let isCommutable = 1 in {
-defm VADD : avx512_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>;
-defm VMUL : avx512_binop_s<0x59, "mul", fmul, SSE_ALU_ITINS_S>;
-defm VMIN : avx512_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>;
-defm VMAX : avx512_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>;
+  defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
+                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
+                            "$src2, $src1", "$src1, $src2",
+                            (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
+                            (i32 FROUND_NO_EXC)), "{sae}">, EVEX_B;
 }
-let isCommutable = 0 in {
-defm VSUB : avx512_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>;
-defm VDIV : avx512_binop_s<0x5E, "div", fdiv, SSE_ALU_ITINS_S>;
+
+multiclass avx512_binop_s_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
+                                  SDNode VecNode,
+                                  SizeItins itins, bit IsCommutable> {
+  defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
+                              itins.s, IsCommutable>,
+             avx512_fp_scalar_round<opc, OpcodeStr#"ss", f32x_info, VecNode,
+                              itins.s, IsCommutable>,
+                              XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
+  defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
+                              itins.d,                  IsCommutable>,
+             avx512_fp_scalar_round<opc, OpcodeStr#"sd", f64x_info, VecNode,
+                              itins.d, IsCommutable>,
+                              XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
+}
+
+multiclass avx512_binop_s_sae<bits<8> opc, string OpcodeStr, SDNode OpNode,
+                                  SDNode VecNode,
+                                  SizeItins itins, bit IsCommutable> {
+  defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
+                              itins.s, IsCommutable>,
+             avx512_fp_scalar_sae<opc, OpcodeStr#"ss", f32x_info, VecNode,
+                              itins.s, IsCommutable>,
+                              XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
+  defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
+                              itins.d,                  IsCommutable>,
+             avx512_fp_scalar_sae<opc, OpcodeStr#"sd", f64x_info, VecNode,
+                              itins.d, IsCommutable>,
+                              XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
 }
+defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnd, SSE_ALU_ITINS_S, 1>;
+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>;
 
 multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
                             X86VectorVTInfo _, bit IsCommutable> {

Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=230891&r1=230890&r2=230891&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Sun Mar  1 01:44:04 2015
@@ -282,6 +282,8 @@ def X86faddRnd   : SDNode<"X86ISD::FADD_
 def X86fsubRnd   : SDNode<"X86ISD::FSUB_RND",  SDTFPBinOpRound>;
 def X86fmulRnd   : SDNode<"X86ISD::FMUL_RND",  SDTFPBinOpRound>;
 def X86fdivRnd   : SDNode<"X86ISD::FDIV_RND",  SDTFPBinOpRound>;
+def X86fmaxRnd   : SDNode<"X86ISD::FMAX",      SDTFPBinOpRound>;
+def X86fminRnd   : SDNode<"X86ISD::FMIN",      SDTFPBinOpRound>;
 
 def X86Fmadd     : SDNode<"X86ISD::FMADD",     SDTFma>;
 def X86Fnmadd    : SDNode<"X86ISD::FNMADD",    SDTFma>;

Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=230891&r1=230890&r2=230891&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Sun Mar  1 01:44:04 2015
@@ -3567,7 +3567,7 @@ multiclass sse1_fp_unop_s<bits<8> opc, s
   defm V#NAME#SS  : avx_fp_unop_s<opc, "v"#OpcodeStr##ss, FR32, v4f32, f32,
                       f32mem, ssmem, sse_load_f32,
                       !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
-                      itins, HasAVX, "SS">, XS, VEX_4V, VEX_LIG;
+                      itins, UseAVX, "SS">, XS, VEX_4V, VEX_LIG;
 }
 
 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
@@ -3579,7 +3579,7 @@ multiclass sse2_fp_unop_s<bits<8> opc, s
   defm V#NAME#SD  : avx_fp_unop_s<opc, "v"#OpcodeStr##sd, FR64, v2f64, f64,
                          f64mem, sdmem, sse_load_f64,
                          !cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
-                         OpNode, itins, HasAVX, "SD">, XD, VEX_4V, VEX_LIG;
+                         OpNode, itins, UseAVX, "SD">, XD, VEX_4V, VEX_LIG;
 }
 
 // Square root.

Added: llvm/trunk/test/CodeGen/X86/avx512-scalar.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx512-scalar.ll?rev=230891&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx512-scalar.ll (added)
+++ llvm/trunk/test/CodeGen/X86/avx512-scalar.ll Sun Mar  1 01:44:04 2015
@@ -0,0 +1,92 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl --show-mc-encoding | FileCheck %s --check-prefix AVX512
+; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx --show-mc-encoding | FileCheck %s --check-prefix AVX
+
+; AVX512-LABEL: @test_fdiv
+; AVX512: vdivss %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_fdiv
+; AVX:    vdivss %xmm{{.*}} ## encoding: [0xc5
+
+define float @test_fdiv(float %a, float %b) {
+  %c = fdiv float %a, %b
+  ret float %c
+}
+
+; AVX512-LABEL: @test_fsub
+; AVX512: vsubss %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_fsub
+; AVX:    vsubss %xmm{{.*}} ## encoding: [0xc5
+
+define float @test_fsub(float %a, float %b) {
+  %c = fsub float %a, %b
+  ret float %c
+}
+
+; AVX512-LABEL: @test_fadd
+; AVX512: vaddsd %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_fadd
+; AVX:    vaddsd %xmm{{.*}} ## encoding: [0xc5
+
+define double @test_fadd(double %a, double %b) {
+  %c = fadd double %a, %b
+  ret double %c
+}
+
+declare float     @llvm.trunc.f32(float  %Val)
+declare double    @llvm.trunc.f64(double %Val)
+declare float     @llvm.rint.f32(float  %Val)
+declare double    @llvm.rint.f64(double %Val)
+declare double    @llvm.sqrt.f64(double %Val)
+declare float     @llvm.sqrt.f32(float  %Val)
+
+; AVX512-LABEL: @test_trunc
+; AVX512: vrndscaless
+; AVX-LABEL: @test_trunc
+; AVX:    vroundss
+
+define float @test_trunc(float %a) {
+  %c = call float @llvm.trunc.f32(float %a)
+  ret float %c
+}
+
+; AVX512-LABEL: @test_sqrt
+; AVX512: vsqrtsd %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_sqrt
+; AVX:    vsqrtsd %xmm{{.*}} ## encoding: [0xc5
+
+define double @test_sqrt(double %a) {
+  %c = call double @llvm.sqrt.f64(double %a)
+  ret double %c
+}
+
+; AVX512-LABEL: @test_rint
+; AVX512: vrndscaless
+; AVX-LABEL: @test_rint
+; AVX:    vroundss
+
+define float @test_rint(float %a) {
+  %c = call float @llvm.rint.f32(float %a)
+  ret float %c
+}
+
+; AVX512-LABEL: @test_vmax
+; AVX512: vmaxss %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_vmax
+; AVX:    vmaxss %xmm{{.*}} ## encoding: [0xc5
+
+define float @test_vmax(float %i, float %j) {
+  %cmp_res = fcmp ogt float %i, %j
+  %max = select i1 %cmp_res, float %i, float %j
+  ret float %max
+}
+
+; AVX512-LABEL: @test_mov
+; AVX512: vcmpltss %xmm{{.*}} ## encoding: [0x62
+; AVX-LABEL: @test_mov
+; AVX:    vcmpltss %xmm{{.*}} ## encoding: [0xc5
+
+define float @test_mov(float %a, float %b, float %i, float %j) {
+  %cmp_res = fcmp ogt float %i, %j
+  %max = select i1 %cmp_res, float %b, float %a
+  ret float %max
+}
+

Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp?rev=230891&r1=230890&r2=230891&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp (original)
+++ llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Sun Mar  1 01:44:04 2015
@@ -215,11 +215,17 @@ static inline bool inheritsFrom(Instruct
     return inheritsFrom(child, IC_EVEX_W_K) ||
            inheritsFrom(child, IC_EVEX_L_W_K);
   case IC_EVEX_XS_K:
+  case IC_EVEX_XS_K_B:
+  case IC_EVEX_XS_KZ_B:
     return inheritsFrom(child, IC_EVEX_W_XS_K) ||
            inheritsFrom(child, IC_EVEX_L_W_XS_K);
   case IC_EVEX_XD_K:
+  case IC_EVEX_XD_K_B:
+  case IC_EVEX_XD_KZ_B:
     return inheritsFrom(child, IC_EVEX_W_XD_K) ||
            inheritsFrom(child, IC_EVEX_L_W_XD_K);
+  case IC_EVEX_XS_B:
+  case IC_EVEX_XD_B:
   case IC_EVEX_K_B:
   case IC_EVEX_KZ:
     return false;
@@ -253,6 +259,12 @@ static inline bool inheritsFrom(Instruct
   case IC_EVEX_W_KZ:
   case IC_EVEX_W_XS_KZ:
   case IC_EVEX_W_XD_KZ:
+  case IC_EVEX_W_XS_B:
+  case IC_EVEX_W_XD_B:
+  case IC_EVEX_W_XS_K_B:
+  case IC_EVEX_W_XD_K_B:
+  case IC_EVEX_W_XS_KZ_B:
+  case IC_EVEX_W_XD_KZ_B:
   case IC_EVEX_W_OPSIZE_KZ:
   case IC_EVEX_W_OPSIZE_KZ_B:
     return false;





More information about the llvm-commits mailing list