[clang] d290424 - [ARM][MVE] Factor out an IntrinsicMX multiclass.

Simon Tatham via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 11 04:07:48 PST 2019


Author: Simon Tatham
Date: 2019-12-11T12:07:26Z
New Revision: d290424731ede31fd5fd75b929df8fe0adb547c7

URL: https://github.com/llvm/llvm-project/commit/d290424731ede31fd5fd75b929df8fe0adb547c7
DIFF: https://github.com/llvm/llvm-project/commit/d290424731ede31fd5fd75b929df8fe0adb547c7.diff

LOG: [ARM][MVE] Factor out an IntrinsicMX multiclass.

Summary:
The ACLE intrinsics for MVE contain a lot of pairs of functions with
`_m` and `_x` in the name, wrapping a predicated MVE instruction which
only partially overwrites its output register. They have the common
pattern that the `_m` variant takes an initial argument called
'inactive', of the same type as the return value, supplying the input
value of the output register, so that lanes disabled by the
predication will be taken from that parameter; the `_x` variant omits
that initial argument, and simply sets it to undef.

That common pattern is simple enough to wrap into a multiclass, which
should save a lot of effort in setting up all the rest of the `_x`
variants. In this commit I introduce `multiclass IntrinsicMX` in
`arm_mve_defs.td`, and convert existing generation of m/x pairs to use
it.

This allows me to remove the `PredicatedImmediateVectorShift`
multiclass (from D71065) completely, because the new multiclass makes
it so much simpler that it's not worth bothering to define it at all.

Reviewers: MarkMurrayARM, miyuki

Reviewed By: MarkMurrayARM, miyuki

Subscribers: kristof.beyls, dmgreen, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D71335

Added: 
    

Modified: 
    clang/include/clang/Basic/arm_mve.td
    clang/include/clang/Basic/arm_mve_defs.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td
index 9b6053e57861..7ed3c04c58db 100644
--- a/clang/include/clang/Basic/arm_mve.td
+++ b/clang/include/clang/Basic/arm_mve.td
@@ -609,30 +609,21 @@ defm vstrhq: scatter_offset_both<!listconcat(T.All16, T.Int32), u16, 1>;
 defm vstrwq: scatter_offset_both<T.All32, u32, 2>;
 defm vstrdq: scatter_offset_both<T.Int64, u64, 3>;
 
-multiclass PredicatedImmediateVectorShift<
-    Immediate immtype, string predIntrName, list<dag> unsignedFlag = []> {
-  foreach predIntr = [IRInt<predIntrName, [Vector, Predicate]>] in {
-    def _m_n: Intrinsic<Vector, (args Vector:$inactive, Vector:$v,
-                                      immtype:$sh, Predicate:$pred),
-       !con((predIntr $v, $sh), !dag(predIntr, unsignedFlag, ?),
-            (predIntr $pred, $inactive))>;
-    def _x_n: Intrinsic<Vector, (args Vector:$v, immtype:$sh,
-                                      Predicate:$pred),
-       !con((predIntr $v, $sh), !dag(predIntr, unsignedFlag, ?),
-            (predIntr $pred, (undef Vector)))>;
-  }
-}
-
 let params = T.Int in {
   def vshlq_n: Intrinsic<Vector, (args Vector:$v, imm_0toNm1:$sh),
                          (shl $v, (splat (Scalar $sh)))>;
-  defm vshlq: PredicatedImmediateVectorShift<imm_0toNm1, "shl_imm_predicated">;
+  defm vshlq: IntrinsicMX<Vector, (args Vector:$v, imm_0toNm1:$sh,
+                                        Predicate:$pred),
+      (IRInt<"shl_imm_predicated", [Vector, Predicate]>
+           $v, $sh, $pred, $inactive), "_n">;
 
   let pnt = PNT_NType in {
     def vshrq_n: Intrinsic<Vector, (args Vector:$v, imm_1toN:$sh),
                             (immshr $v, $sh, (unsignedflag Scalar))>;
-    defm vshrq: PredicatedImmediateVectorShift<imm_1toN, "shr_imm_predicated",
-                                     [(unsignedflag Scalar)]>;
+    defm vshrq: IntrinsicMX<Vector, (args Vector:$v, imm_1toN:$sh,
+                                          Predicate:$pred),
+        (IRInt<"shr_imm_predicated", [Vector, Predicate]>
+             $v, $sh, (unsignedflag Scalar), $pred, $inactive), "_n">;
   }
 }
 
@@ -713,25 +704,17 @@ def vadciq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
 multiclass VectorComplexAddPred<dag not_halving, dag angle> {
   def "" : Intrinsic<Vector, (args Vector:$a, Vector:$b),
      (IRInt<"vcaddq", [Vector]> not_halving, angle, $a, $b)>;
-  def _m : Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
-                              Predicate:$pred),
+  defm "" : IntrinsicMX<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
      (IRInt<"vcaddq_predicated", [Vector, Predicate]>
        not_halving, angle, $inactive, $a, $b, $pred)>;
-  def _x : Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
-     (IRInt<"vcaddq_predicated", [Vector, Predicate]>
-       not_halving, angle, (undef Vector), $a, $b, $pred)>;
 }
 
 multiclass VectorComplexMulPred<dag angle> {
   def "" : Intrinsic<Vector, (args Vector:$a, Vector:$b),
     (IRInt<"vcmulq", [Vector]> angle, $a, $b)>;
-  def _m : Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
-                              Predicate:$pred),
+  defm "" : IntrinsicMX<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
     (IRInt<"vcmulq_predicated", [Vector, Predicate]> angle, $inactive, $a, $b,
       $pred)>;
-  def _x : Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred),
-    (IRInt<"vcmulq_predicated", [Vector, Predicate]> angle, (undef Vector), $a,
-      $b, $pred)>;
 }
 
 multiclass VectorComplexMLAPred<dag angle> {

diff  --git a/clang/include/clang/Basic/arm_mve_defs.td b/clang/include/clang/Basic/arm_mve_defs.td
index 6bc9b35f0fc4..3e22e44607ca 100644
--- a/clang/include/clang/Basic/arm_mve_defs.td
+++ b/clang/include/clang/Basic/arm_mve_defs.td
@@ -432,6 +432,30 @@ class NameOverride<string basename_> {
   string basename = basename_;
 }
 
+// A wrapper to define both _m and _x versions of a predicated
+// intrinsic.
+multiclass IntrinsicMX<Type rettype, dag arguments, dag cg,
+                       string nameSuffix = "",
+                       PolymorphicNameType pnt_x = PNT_Type> {
+  // The _m variant takes an initial parameter called $inactive, which
+  // provides the input value of the output register, i.e. all the
+  // inactive lanes in the predicated operation take their values from
+  // this.
+  def "_m" # nameSuffix:
+     Intrinsic<rettype, !con((args rettype:$inactive), arguments), cg>;
+
+  // The _x variant leaves off that parameter, and simply uses an
+  // undef value of the same type.
+  def "_x" # nameSuffix:
+     Intrinsic<rettype, arguments, (seq (undef rettype):$inactive, cg)> {
+    // Allow overriding of the polymorphic name type, because
+    // sometimes the _m and _x variants polymorph 
diff erently
+    // (typically because the type of the inactive parameter can be
+    // used as a disambiguator if it's present).
+    let pnt = pnt_x;
+  }
+}
+
 // -----------------------------------------------------------------------------
 // Convenience lists of parameter types. 'T' is just a container record, so you
 // can define a typical intrinsic with 'let Params = T.Usual', or similar,


        


More information about the cfe-commits mailing list