@@ -2160,6 +2160,43 @@ static mlir::Value buildArmLdrexNon128Intrinsic(unsigned int builtinID,
21602160 }
21612161}
21622162
2163+ // / Given a vector of unsigned int type `vecTy`, return a vector type of
2164+ // / signed int type with the same element type width and vector size.
2165+ static mlir::cir::VectorType getSignedVectorType (CIRGenBuilderTy &builder,
2166+ mlir::cir::VectorType vecTy) {
2167+ auto elemTy = mlir::cast<mlir::cir::IntType>(vecTy.getEltType ());
2168+ elemTy = builder.getSIntNTy (elemTy.getWidth ());
2169+ return mlir::cir::VectorType::get (builder.getContext (), elemTy,
2170+ vecTy.getSize ());
2171+ }
2172+
2173+ // / Get integer from a mlir::Value that is an int constant or a constant op.
2174+ static int64_t getIntValueFromConstOp (mlir::Value val) {
2175+ auto constOp = mlir::cast<mlir::cir::ConstantOp>(val.getDefiningOp ());
2176+ return (mlir::cast<mlir::cir::IntAttr>(constOp.getValue ()))
2177+ .getValue ()
2178+ .getSExtValue ();
2179+ }
2180+
2181+ // / Build a constant shift amount vector of `vecTy` to shift a vector
2182+ // / Here `shitfVal` is a constant integer that will be splated into a
2183+ // / a const vector of `vecTy` which is the return of this function
2184+ static mlir::Value buildNeonShiftVector (CIRGenBuilderTy &builder,
2185+ mlir::Value shiftVal,
2186+ mlir::cir::VectorType vecTy,
2187+ mlir::Location loc, bool neg) {
2188+ int shiftAmt = getIntValueFromConstOp (shiftVal);
2189+ if (neg)
2190+ shiftAmt = -shiftAmt;
2191+ llvm::SmallVector<mlir::Attribute> vecAttr{
2192+ vecTy.getSize (),
2193+ // ConstVectorAttr requires cir::IntAttr
2194+ mlir::cir::IntAttr::get (vecTy.getEltType (), shiftAmt)};
2195+ mlir::cir::ConstVectorAttr constVecAttr = mlir::cir::ConstVectorAttr::get (
2196+ vecTy, mlir::ArrayAttr::get (builder.getContext (), vecAttr));
2197+ return builder.create <mlir::cir::ConstantOp>(loc, vecTy, constVecAttr);
2198+ }
2199+
21632200mlir::Value buildNeonCall (CIRGenBuilderTy &builder,
21642201 llvm::SmallVector<mlir::Type> argTypes,
21652202 llvm::SmallVectorImpl<mlir::Value> &args,
@@ -2172,38 +2209,27 @@ mlir::Value buildNeonCall(CIRGenBuilderTy &builder,
21722209 assert (!MissingFeatures::buildConstrainedFPCall ());
21732210 if (isConstrainedFPIntrinsic)
21742211 llvm_unreachable (" isConstrainedFPIntrinsic NYI" );
2175- // TODO: Remove the following unreachable and call it in the loop once
2176- // there is an implementation of buildNeonShiftVector
2177- if (shift > 0 )
2178- llvm_unreachable (" Argument shift NYI" );
21792212
21802213 for (unsigned j = 0 ; j < argTypes.size (); ++j) {
21812214 if (isConstrainedFPIntrinsic) {
21822215 assert (!MissingFeatures::buildConstrainedFPCall ());
21832216 }
21842217 if (shift > 0 && shift == j) {
2185- assert (!MissingFeatures::buildNeonShiftVector ());
2218+ args[j] = buildNeonShiftVector (
2219+ builder, args[j], mlir::cast<mlir::cir::VectorType>(argTypes[j]), loc,
2220+ rightshift);
21862221 } else {
21872222 args[j] = builder.createBitcast (args[j], argTypes[j]);
21882223 }
21892224 }
21902225 if (isConstrainedFPIntrinsic) {
21912226 assert (!MissingFeatures::buildConstrainedFPCall ());
21922227 return nullptr ;
2193- } else {
2194- return builder
2195- .create <mlir::cir::IntrinsicCallOp>(
2196- loc, builder.getStringAttr (intrinsicName), funcResTy, args)
2197- .getResult ();
21982228 }
2199- }
2200-
2201- // / Get integer from a mlir::Value that is an int constant or a constant op.
2202- static int64_t getIntValueFromConstOp (mlir::Value val) {
2203- auto constOp = mlir::cast<mlir::cir::ConstantOp>(val.getDefiningOp ());
2204- return (mlir::cast<mlir::cir::IntAttr>(constOp.getValue ()))
2205- .getValue ()
2206- .getSExtValue ();
2229+ return builder
2230+ .create <mlir::cir::IntrinsicCallOp>(
2231+ loc, builder.getStringAttr (intrinsicName), funcResTy, args)
2232+ .getResult ();
22072233}
22082234
22092235// / This function `buildCommonNeonCallPattern0` implements a common way
@@ -2231,23 +2257,6 @@ buildCommonNeonCallPattern0(CIRGenFunction &cgf, llvm::StringRef intrincsName,
22312257 return builder.createBitcast (res, resultType);
22322258}
22332259
2234- // / Build a constant shift amount vector of `vecTy` to shift a vector
2235- // / Here `shitfVal` is a constant integer that will be splated into a
2236- // / a const vector of `vecTy` which is the return of this function
2237- static mlir::Value buildNeonShiftVector (CIRGenBuilderTy &builder,
2238- mlir::Value shiftVal,
2239- mlir::cir::VectorType vecTy,
2240- mlir::Location loc, bool neg) {
2241- int shiftAmt = getIntValueFromConstOp (shiftVal);
2242- llvm::SmallVector<mlir::Attribute> vecAttr{
2243- vecTy.getSize (),
2244- // ConstVectorAttr requires cir::IntAttr
2245- mlir::cir::IntAttr::get (vecTy.getEltType (), shiftAmt)};
2246- mlir::cir::ConstVectorAttr constVecAttr = mlir::cir::ConstVectorAttr::get (
2247- vecTy, mlir::ArrayAttr::get (builder.getContext (), vecAttr));
2248- return builder.create <mlir::cir::ConstantOp>(loc, vecTy, constVecAttr);
2249- }
2250-
22512260// / Build ShiftOp of vector type whose shift amount is a vector built
22522261// / from a constant integer using `buildNeonShiftVector` function
22532262static mlir::Value buildCommonNeonShift (CIRGenBuilderTy &builder,
@@ -2345,6 +2354,15 @@ mlir::Value CIRGenFunction::buildCommonNeonBuiltinExpr(
23452354 : " llvm.aarch64.neon.sqrdmulh.lane" ,
23462355 resTy, getLoc (e->getExprLoc ()));
23472356 }
2357+ case NEON::BI__builtin_neon_vrshr_n_v:
2358+ case NEON::BI__builtin_neon_vrshrq_n_v: {
2359+ return buildNeonCall (
2360+ builder, {vTy, isUnsigned ? getSignedVectorType (builder, vTy) : vTy},
2361+ ops, isUnsigned ? " llvm.aarch64.neon.urshl" : " llvm.aarch64.neon.srshl" ,
2362+ vTy, getLoc (e->getExprLoc ()), false , /* not fp constrained op*/
2363+ 1 , /* second arg is shift amount */
2364+ true /* rightshift */ );
2365+ }
23482366 case NEON::BI__builtin_neon_vshl_n_v:
23492367 case NEON::BI__builtin_neon_vshlq_n_v: {
23502368 mlir::Location loc = getLoc (e->getExprLoc ());
0 commit comments