diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td --- a/clang/include/clang/Basic/arm_mve.td +++ b/clang/include/clang/Basic/arm_mve.td @@ -610,17 +610,10 @@ defm vstrdq: scatter_offset_both; multiclass PredicatedImmediateVectorShift< - Immediate immtype, string predIntrName, list unsignedFlag = []> { - foreach predIntr = [IRInt] in { - def _m_n: Intrinsic; - def _x_n: Intrinsic; - } + Immediate immtype, string predIntrName, dag unsignedFlag = (?)> { + defm "": IntrinsicMX $v, $sh), + unsignedFlag, (? $pred, $inactive)), "_n">; } let params = T.Int in { @@ -632,7 +625,7 @@ def vshrq_n: Intrinsic; defm vshrq: PredicatedImmediateVectorShift; + (? (unsignedflag Scalar))>; } } @@ -713,25 +706,17 @@ multiclass VectorComplexAddPred { def "" : Intrinsic not_halving, angle, $a, $b)>; - def _m : Intrinsic not_halving, angle, $inactive, $a, $b, $pred)>; - def _x : Intrinsic - not_halving, angle, (undef Vector), $a, $b, $pred)>; } multiclass VectorComplexMulPred { def "" : Intrinsic angle, $a, $b)>; - def _m : Intrinsic angle, $inactive, $a, $b, $pred)>; - def _x : Intrinsic angle, (undef Vector), $a, - $b, $pred)>; } multiclass VectorComplexMLAPred { diff --git a/clang/include/clang/Basic/arm_mve_defs.td b/clang/include/clang/Basic/arm_mve_defs.td --- a/clang/include/clang/Basic/arm_mve_defs.td +++ b/clang/include/clang/Basic/arm_mve_defs.td @@ -432,6 +432,30 @@ string basename = basename_; } +// A wrapper to define both _m and _x versions of a predicated +// intrinsic. +multiclass IntrinsicMX { + // 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; + + // The _x variant leaves off that parameter, and simply uses an + // undef value of the same type. + def "_x" # nameSuffix: + Intrinsic { + // Allow overriding of the polymorphic name type, because + // sometimes the _m and _x variants polymorph differently + // (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,