@@ -3192,7 +3192,7 @@ static mlir::Value buildArmLdrexNon128Intrinsic(unsigned int builtinID,
3192
3192
}
3193
3193
}
3194
3194
3195
- mlir::Value buildNeonCall (unsigned int builtinID, CIRGenFunction &cgf ,
3195
+ mlir::Value buildNeonCall (CIRGenBuilderTy &builder ,
3196
3196
llvm::SmallVector<mlir::Type> argTypes,
3197
3197
llvm::SmallVectorImpl<mlir::Value> &args,
3198
3198
llvm::StringRef intrinsicName, mlir::Type funcResTy,
@@ -3209,7 +3209,6 @@ mlir::Value buildNeonCall(unsigned int builtinID, CIRGenFunction &cgf,
3209
3209
if (shift > 0 )
3210
3210
llvm_unreachable (" Argument shift NYI" );
3211
3211
3212
- CIRGenBuilderTy &builder = cgf.getBuilder ();
3213
3212
for (unsigned j = 0 ; j < argTypes.size (); ++j) {
3214
3213
if (isConstrainedFPIntrinsic) {
3215
3214
assert (!MissingFeatures::buildConstrainedFPCall ());
@@ -3239,6 +3238,24 @@ static int64_t getIntValueFromConstOp(mlir::Value val) {
3239
3238
.getSExtValue ();
3240
3239
}
3241
3240
3241
+ // / This function `buildCommonNeonCallPattern0` implements a common way
3242
+ // to generate neon intrinsic call that has following pattern:
3243
+ // 1. There is a need to cast result of the intrinsic call back to
3244
+ // expression type.
3245
+ // 2. Function arg types are given, not deduced from actual arg types.
3246
+ static mlir::Value
3247
+ buildCommonNeonCallPattern0 (CIRGenFunction &cgf, std::string &intrincsName,
3248
+ llvm::SmallVector<mlir::Type> argTypes,
3249
+ llvm::SmallVectorImpl<mlir::Value> &ops,
3250
+ mlir::Type funcResTy, const clang::CallExpr *e) {
3251
+ CIRGenBuilderTy &builder = cgf.getBuilder ();
3252
+ mlir::Value res =
3253
+ buildNeonCall (builder, std::move (argTypes), ops, intrincsName, funcResTy,
3254
+ cgf.getLoc (e->getExprLoc ()));
3255
+ mlir::Type resultType = cgf.ConvertType (e->getType ());
3256
+ return builder.createBitcast (res, resultType);
3257
+ }
3258
+
3242
3259
mlir::Value CIRGenFunction::buildCommonNeonBuiltinExpr (
3243
3260
unsigned builtinID, unsigned llvmIntrinsic, unsigned altLLVMIntrinsic,
3244
3261
const char *nameHint, unsigned modifier, const CallExpr *e,
@@ -3303,18 +3320,25 @@ mlir::Value CIRGenFunction::buildCommonNeonBuiltinExpr(
3303
3320
default :
3304
3321
llvm::errs () << getAArch64SIMDIntrinsicString (builtinID) << " " ;
3305
3322
llvm_unreachable (" NYI" );
3306
- case NEON::BI__builtin_neon_vqadd_v:
3307
- mlir::Value res = buildNeonCall (builtinID, *this , {vTy, vTy}, ops,
3308
- (intrinicId != altLLVMIntrinsic)
3309
- ? " llvm.aarch64.neon.uqadd"
3310
- : " llvm.aarch64.neon.sqadd" ,
3311
- vTy, getLoc (e->getExprLoc ()));
3312
- mlir::Type resultType = ConvertType (e->getType ());
3313
- // AArch64 intrinsic one-element vector type cast to
3314
- // scalar type expected by the builtin
3315
- return builder.createBitcast (res, resultType);
3323
+
3324
+ case NEON::BI__builtin_neon_vpadd_v:
3325
+ case NEON::BI__builtin_neon_vpaddq_v: {
3326
+ std::string intrincsName = mlir::isa<mlir::FloatType>(vTy.getEltType ())
3327
+ ? " llvm.aarch64.neon.faddp"
3328
+ : " llvm.aarch64.neon.addp" ;
3329
+ return buildCommonNeonCallPattern0 (*this , intrincsName, {vTy, vTy}, ops,
3330
+ vTy, e);
3316
3331
break ;
3317
3332
}
3333
+ case NEON::BI__builtin_neon_vqadd_v: {
3334
+ std::string intrincsName = (intrinicId != altLLVMIntrinsic)
3335
+ ? " llvm.aarch64.neon.uqadd"
3336
+ : " llvm.aarch64.neon.sqadd" ;
3337
+ return buildCommonNeonCallPattern0 (*this , intrincsName, {vTy, vTy}, ops,
3338
+ vTy, e);
3339
+ break ;
3340
+ }
3341
+ }
3318
3342
return nullptr ;
3319
3343
}
3320
3344
0 commit comments