@@ -463,12 +463,107 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
463463 return emitLibraryCall (*this , fd, e,
464464 cgm.getBuiltinLibFunction (fd, builtinID));
465465
466+ // Some target-specific builtins can have aggregate return values, e.g.
467+ // __builtin_arm_mve_vld2q_u32. So if the result is an aggregate, force
468+ // returnValue to be non-null, so that the target-specific emission code can
469+ // always just emit into it.
470+ cir::TypeEvaluationKind evalKind = getEvaluationKind (e->getType ());
471+ if (evalKind == cir::TEK_Aggregate && returnValue.isNull ()) {
472+ cgm.errorNYI (e->getSourceRange (), " aggregate return value from builtin" );
473+ return getUndefRValue (e->getType ());
474+ }
475+
476+ // Now see if we can emit a target-specific builtin.
477+ if (mlir::Value v = emitTargetBuiltinExpr (builtinID, e, returnValue)) {
478+ switch (evalKind) {
479+ case cir::TEK_Scalar:
480+ if (mlir::isa<cir::VoidType>(v.getType ()))
481+ return RValue::get (nullptr );
482+ return RValue::get (v);
483+ case cir::TEK_Aggregate:
484+ cgm.errorNYI (e->getSourceRange (), " aggregate return value from builtin" );
485+ return getUndefRValue (e->getType ());
486+ case cir::TEK_Complex:
487+ llvm_unreachable (" No current target builtin returns complex" );
488+ }
489+ llvm_unreachable (" Bad evaluation kind in EmitBuiltinExpr" );
490+ }
491+
466492 cgm.errorNYI (e->getSourceRange (),
467493 std::string (" unimplemented builtin call: " ) +
468494 getContext ().BuiltinInfo .getName (builtinID));
469495 return getUndefRValue (e->getType ());
470496}
471497
498+ static mlir::Value emitTargetArchBuiltinExpr (CIRGenFunction *cgf,
499+ unsigned builtinID,
500+ const CallExpr *e,
501+ ReturnValueSlot &returnValue,
502+ llvm::Triple::ArchType arch) {
503+ // When compiling in HipStdPar mode we have to be conservative in rejecting
504+ // target specific features in the FE, and defer the possible error to the
505+ // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
506+ // referenced by an accelerator executable function, we emit an error.
507+ // Returning nullptr here leads to the builtin being handled in
508+ // EmitStdParUnsupportedBuiltin.
509+ if (cgf->getLangOpts ().HIPStdPar && cgf->getLangOpts ().CUDAIsDevice &&
510+ arch != cgf->getTarget ().getTriple ().getArch ())
511+ return {};
512+
513+ switch (arch) {
514+ case llvm::Triple::arm:
515+ case llvm::Triple::armeb:
516+ case llvm::Triple::thumb:
517+ case llvm::Triple::thumbeb:
518+ case llvm::Triple::aarch64:
519+ case llvm::Triple::aarch64_32:
520+ case llvm::Triple::aarch64_be:
521+ case llvm::Triple::bpfeb:
522+ case llvm::Triple::bpfel:
523+ // These are actually NYI, but that will be reported by emitBuiltinExpr.
524+ // At this point, we don't even know that the builtin is target-specific.
525+ return nullptr ;
526+
527+ case llvm::Triple::x86:
528+ case llvm::Triple::x86_64:
529+ return cgf->emitX86BuiltinExpr (builtinID, e);
530+
531+ case llvm::Triple::ppc:
532+ case llvm::Triple::ppcle:
533+ case llvm::Triple::ppc64:
534+ case llvm::Triple::ppc64le:
535+ case llvm::Triple::r600:
536+ case llvm::Triple::amdgcn:
537+ case llvm::Triple::systemz:
538+ case llvm::Triple::nvptx:
539+ case llvm::Triple::nvptx64:
540+ case llvm::Triple::wasm32:
541+ case llvm::Triple::wasm64:
542+ case llvm::Triple::hexagon:
543+ case llvm::Triple::riscv32:
544+ case llvm::Triple::riscv64:
545+ // These are actually NYI, but that will be reported by emitBuiltinExpr.
546+ // At this point, we don't even know that the builtin is target-specific.
547+ return {};
548+ default :
549+ return {};
550+ }
551+ }
552+
553+ mlir::Value
554+ CIRGenFunction::emitTargetBuiltinExpr (unsigned builtinID, const CallExpr *e,
555+ ReturnValueSlot &returnValue) {
556+ if (getContext ().BuiltinInfo .isAuxBuiltinID (builtinID)) {
557+ assert (getContext ().getAuxTargetInfo () && " Missing aux target info" );
558+ return emitTargetArchBuiltinExpr (
559+ this , getContext ().BuiltinInfo .getAuxBuiltinID (builtinID), e,
560+ returnValue, getContext ().getAuxTargetInfo ()->getTriple ().getArch ());
561+ }
562+
563+ return emitTargetArchBuiltinExpr (this , builtinID, e, returnValue,
564+ getTarget ().getTriple ().getArch ());
565+ }
566+
472567// / Given a builtin id for a function like "__builtin_fabsf", return a Function*
473568// / for "fabsf".
474569cir::FuncOp CIRGenModule::getBuiltinLibFunction (const FunctionDecl *fd,
0 commit comments