================
@@ -369,12 +369,96 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr(
case NEON::BI__builtin_neon_vmaxv_f32:
case NEON::BI__builtin_neon_vmaxvq_f32:
case NEON::BI__builtin_neon_vmaxvq_f64:
- return emitNeonCall(cgf.cgm, cgf.getBuilder(),
- {cgf.convertType(expr->getArg(0)->getType())}, ops,
- llvmIntrName, cgf.convertType(expr->getType()), loc);
+ case NEON::BI__builtin_neon_vsrid_n_s64:
+ case NEON::BI__builtin_neon_vsrid_n_u64:
+ break;
}
- return nullptr;
+ // Generic handling based on TypeModifier flags, mirroring
+ // EmitCommonNeonSISDBuiltinExpr + LookupNeonLLVMIntrinsic in ARM.cpp.
+ //
+ // The TypeModifier encodes how the intrinsic's argument and return types
+ // relate to the builtin's scalar types. For SISD builtins the key flags
+ // are:
+ // - VectorizeArgTypes: wrap each arg type into a fixed-width vector
+ // - Use64BitVectors / Use128BitVectors: choose the vector width
+ // (when neither is set the vector has 1 element)
+ // - AddRetType / VectorizeRetType: analogous flags for the return type
+ //
+ // ARM.cpp doesn't need to know about specific builtins like
+ // `vsrid_n_{s,u}64` because it lets LLVM resolve the intrinsic's
+ // signature (via `CGM.getIntrinsic`) and then walks the resolved
+ // Function* formal parameter types. CIR has no LLVMContext here, so
+ // we derive the same argument/result types directly from the Clang
+ // operand types.
+
+ unsigned modifier = info.TypeModifier;
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+ mlir::Type argTy = cgf.convertType(expr->getArg(0)->getType());
+ mlir::Type resultTy = cgf.convertType(expr->getType());
+
+ int vectorSize = 0;
+ if (modifier & Use64BitVectors)
+ vectorSize = 64;
+ else if (modifier & Use128BitVectors)
+ vectorSize = 128;
+
+ auto wrapAsVector = [&](mlir::Type ty) -> cir::VectorType {
+ unsigned bits = cgf.cgm.getDataLayout().getTypeSizeInBits(ty);
+ unsigned elts = vectorSize ? vectorSize / bits : 1;
+ return cir::VectorType::get(ty, elts);
+ };
+
+ // Determine the vectorized data type.
+ cir::VectorType vecArgTy;
+ if (modifier & VectorizeArgTypes)
+ vecArgTy = wrapAsVector(argTy);
+
+ // Determine the intrinsic result type: `VectorizeRetType` returns a
+ // vector; otherwise, if data args are vectorized and `AddRetType` is
+ // unset, use a vector return with the same shape as those args.
+ mlir::Type funcResTy = resultTy;
+ if (modifier & VectorizeRetType)
+ funcResTy = wrapAsVector(resultTy);
+ else if (vecArgTy && !(modifier & AddRetType))
+ funcResTy = wrapAsVector(resultTy);
+
+ // Build the arg types for `emitNeonCall`.
+ llvm::SmallVector<mlir::Type> argTypes;
+ argTypes.reserve(ops.size());
+ for (mlir::Value op : ops) {
+ if (vecArgTy && op.getType() == argTy)
+ argTypes.push_back(vecArgTy);
+ else
+ argTypes.push_back(op.getType());
+ }
----------------
banach-space wrote:
I think that I know what you mean. Just to satisfy my curiosity - would you be
able to point me to a specific builtin/intrinsic that would be a problem here?
Perhaps it's all of them?
It's just a bit odd that we are not using the modifiers in this case :/ Every
intrinsics that you test in this PR takes exactly 3 arguments with the last one
being an immediate. I'd hope `Add1ArgType` / `Add2ArgTypes` would encode all
the info that we need, but I guess I am missing something here đ€
https://github.com/llvm/llvm-project/pull/196776
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits