[AVX512] Add masking variant and intrinsics for valignd/q
[oota-llvm.git] / lib / Target / X86 / X86InstrAVX512.td
index 7328d992c1f572bd3bd2bacc70e2592de077cdfc..5284c3f65109c3ffa328ab289cb50c1f06d63676 100644 (file)
@@ -4461,9 +4461,9 @@ def : Pat<(v8i64 (X86Shufp VR512:$src1,
                             (memopv8i64 addr:$src2), (i8 imm:$imm))),
           (VSHUFPDZrmi VR512:$src1, addr:$src2, imm:$imm)>;
 
-multiclass avx512_valign<string Suffix, RegisterClass RC,
-                         X86MemOperand x86memop, ValueType IntVT,
-                         ValueType FloatVT> {
+multiclass avx512_valign<string Suffix, RegisterClass RC, RegisterClass KRC,
+                         RegisterClass MRC, X86MemOperand x86memop,
+                         ValueType IntVT, ValueType FloatVT> {
   def rri : AVX512AIi8<0x03, MRMSrcReg, (outs RC:$dst),
                      (ins RC:$src1, RC:$src2, i8imm:$src3),
                      !strconcat("valign"##Suffix,
@@ -4473,10 +4473,39 @@ multiclass avx512_valign<string Suffix, RegisterClass RC,
                            (IntVT (X86VAlign RC:$src2, RC:$src1,
                                               (i8 imm:$src3))))]>, EVEX_4V;
 
+  let Constraints = "$src0 = $dst", AddedComplexity=30 in
+  def rrik : AVX512AIi8<0x03, MRMSrcReg, (outs RC:$dst),
+                     (ins RC:$src0, KRC:$mask, RC:$src1, RC:$src2, i8imm:$src3),
+                     !strconcat("valign"##Suffix,
+                     " \t{$src3, $src2, $src1, $mask, $dst|"
+                         "$dst, $mask, $src1, $src2, $src3}"),
+                     [(set RC:$dst,
+                           (IntVT (vselect KRC:$mask,
+                                     (X86VAlign RC:$src2, RC:$src1,
+                                                (i8 imm:$src3)),
+                                     RC:$src0)))]>,
+             EVEX_4V, EVEX_K;
+
   // Also match valign of packed floats.
   def : Pat<(FloatVT (X86VAlign RC:$src1, RC:$src2, (i8 imm:$imm))),
             (!cast<Instruction>(NAME##rri) RC:$src2, RC:$src1, imm:$imm)>;
 
+  // Non-masking intrinsic call.
+  def : Pat<(IntVT
+               (!cast<Intrinsic>("int_x86_avx512_mask_valign_"##Suffix##"_512")
+                     RC:$src1, RC:$src2, imm:$src3,
+                     (IntVT (bitconvert (v16i32 immAllZerosV))), -1)),
+            (!cast<Instruction>(NAME#rri) RC:$src1, RC:$src2, imm:$src3)>;
+
+  // Masking intrinsic call.
+  def : Pat<(IntVT
+               (!cast<Intrinsic>("int_x86_avx512_mask_valign_"##Suffix##"_512")
+                     RC:$src1, RC:$src2, imm:$src3,
+                     RC:$src4, MRC:$mask)),
+            (!cast<Instruction>(NAME#rrik) RC:$src4,
+               (COPY_TO_REGCLASS MRC:$mask, KRC), RC:$src1,
+               RC:$src2, imm:$src3)>;
+
   let mayLoad = 1 in
   def rmi : AVX512AIi8<0x03, MRMSrcMem, (outs RC:$dst),
                      (ins RC:$src1, x86memop:$src2, i8imm:$src3),
@@ -4485,9 +4514,9 @@ multiclass avx512_valign<string Suffix, RegisterClass RC,
                          "$dst, $src1, $src2, $src3}"),
                      []>, EVEX_4V;
 }
-defm VALIGND : avx512_valign<"d", VR512, i512mem, v16i32, v16f32>,
+defm VALIGND : avx512_valign<"d", VR512, VK16WM, GR16, i512mem, v16i32, v16f32>,
                  EVEX_V512, EVEX_CD8<32, CD8VF>;
-defm VALIGNQ : avx512_valign<"q", VR512, i512mem, v8i64, v8f64>,
+defm VALIGNQ : avx512_valign<"q", VR512, VK8WM, GR8, i512mem, v8i64, v8f64>,
                  VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
 
 // Helper fragments to match sext vXi1 to vXiY.