[AVX512] Generate masking instruction variants with tablegen
authorAdam Nemet <anemet@apple.com>
Thu, 7 Aug 2014 17:53:55 +0000 (17:53 +0000)
committerAdam Nemet <anemet@apple.com>
Thu, 7 Aug 2014 17:53:55 +0000 (17:53 +0000)
After adding the masking variants to several instructions, I have decided to
experiment with generating these from the non-masking/unconditional
variant. This will hopefully reduce the amount repetition that we currently
have in order to define an instruction with all its variants (for a reg/mem
instruction this would be 6 instruction defs and 2 Pat<> for the intrinsic).

The patch is the first cut that is currently only applied to valignd/q to make
the patch small.

A few notes on the approach:

  * In order to stitch together the dag for both the conditional and the
  unconditional patterns I pass the RHS of the set rather than the full
  pattern (set dest, RHS).
  * Rather than subclassing each instruction base class (e.g. AVX512AIi8),
  with a masking variant which wouldn't scale, I derived the masking
  instructions from a new base class AVX512 (this is just I<> with
  Requires<HasAVX512>).  The instructions derive from this now, plus a new set
  of classes that add the format bits and everything else that instruction
  base class provided (i.e. AVX512AIi8 vs. AVX512AIi8Base).

I hope we can go incrementally from here.  I expect that:

  * We will need different variants of the masking class.  One example is
  instructions requiring three vector sources.  In this case we tie one of the
  source operands to dest rather than a new implicit source operand ($src0)
  * Add the zero-masking variant
  * Add more AVX512*Base classes as new uses are added

I've looked at X86.td.expanded before and after to make sure that nothing got
lost for valignd/q.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215125 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrAVX512.td
lib/Target/X86/X86InstrFormats.td

index 122f629..2dcf368 100644 (file)
@@ -1,3 +1,23 @@
+multiclass AVX512_masking<bits<8> O, Format F, dag Outs, dag Ins,
+                              string OpcodeStr,
+                              string AttSrcAsm, string IntelSrcAsm,
+                              dag RHS,
+                              RegisterClass RC, RegisterClass KRC> {
+  def NAME: AVX512<O, F, Outs, Ins,
+                       OpcodeStr#" \t{"#AttSrcAsm#", $dst|"#
+                                      "$dst, "#IntelSrcAsm#"}",
+                       [(set RC:$dst, RHS)]>;
+
+  let Constraints = "$src0 = $dst" in
+  def NAME#k: AVX512<O, F, Outs,
+                       !con((ins RC:$src0, KRC:$mask), Ins),
+                       OpcodeStr#" \t{"#AttSrcAsm#", $dst {${mask}}|"#
+                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
+                       [(set RC:$dst,
+                             (vselect KRC:$mask, RHS, RC:$src0))]>,
+              EVEX_K;
+}
+
 // Bitcasts between 512-bit vector types. Return the original type since
 // no instruction is needed for the conversion
 let Predicates = [HasAVX512] in {
@@ -4464,27 +4484,14 @@ def : Pat<(v8i64 (X86Shufp VR512:$src1,
 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),
+  defm rri : AVX512_masking<0x03, MRMSrcReg, (outs RC:$dst),
                      (ins RC:$src1, RC:$src2, i8imm:$src3),
-                     !strconcat("valign"##Suffix,
-                     " \t{$src3, $src2, $src1, $dst|"
-                         "$dst, $src1, $src2, $src3}"),
-                     [(set RC:$dst,
-                           (IntVT (X86VAlign RC:$src2, RC:$src1,
-                                              (i8 imm:$src3))))]>, EVEX_4V;
-
-  let Constraints = "$src0 = $dst" 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, $dst {${mask}}|"
-                         "$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;
+                     "valign"##Suffix,
+                     "$src3, $src2, $src1", "$src1, $src2, $src3",
+                     (IntVT (X86VAlign RC:$src2, RC:$src1,
+                                       (i8 imm:$src3))),
+                     RC, KRC>,
+             AVX512AIi8Base, EVEX_4V;
 
   // Also match valign of packed floats.
   def : Pat<(FloatVT (X86VAlign RC:$src1, RC:$src2, (i8 imm:$imm))),
index b266bb7..61ea18d 100644 (file)
@@ -722,6 +722,10 @@ class AVX512AIi8<bits<8> o, Format F, dag outs, dag ins, string asm,
               list<dag> pattern, InstrItinClass itin = NoItinerary>
       : Ii8<o, F, outs, ins, asm, pattern, itin, SSEPackedInt>, TAPD,
         Requires<[HasAVX512]>;
+class AVX512AIi8Base: TAPD {
+  Domain ExeDomain = SSEPackedInt;
+  ImmType ImmT = Imm8;
+}
 class AVX512Ii8<bits<8> o, Format F, dag outs, dag ins, string asm,
               list<dag> pattern, InstrItinClass itin = NoItinerary>
       : Ii8<o, F, outs, ins, asm, pattern, itin, SSEPackedInt>,
@@ -745,6 +749,10 @@ class AVX512FMA3<bits<8> o, Format F, dag outs, dag ins, string asm,
       : I<o, F, outs, ins, asm, pattern, itin>, T8PD,
         EVEX_4V, Requires<[HasAVX512]>;
 
+class AVX512<bits<8> o, Format F, dag outs, dag ins, string asm,
+           list<dag>pattern, InstrItinClass itin = NoItinerary>
+      : I<o, F, outs, ins, asm, pattern, itin>, Requires<[HasAVX512]>;
+
 // AES Instruction Templates:
 //
 // AES8I