@@ -94,14 +94,74 @@ static RValue emitUnaryFPBuiltin(CIRGenFunction &cgf, const CallExpr &e) {
9494}
9595
9696static RValue errorBuiltinNYI (CIRGenFunction &cgf, const CallExpr *e,
97- unsigned builtinID) {
97+ unsigned builtinID) {
9898 cgf.cgm .errorNYI (e->getSourceRange (),
99- std::string (" unimplemented X86 builtin call: " ) +
100- cgf.getContext ().BuiltinInfo .getName (builtinID));
99+ std::string (" unimplemented X86 builtin call: " ) +
100+ cgf.getContext ().BuiltinInfo .getName (builtinID));
101101
102102 return cgf.getUndefRValue (e->getType ());
103103}
104104
105+ static RValue emitBuiltinAlloca (CIRGenFunction &cgf, const CallExpr *e,
106+ unsigned builtinID) {
107+ assert (builtinID == Builtin::BI__builtin_alloca ||
108+ builtinID == Builtin::BI__builtin_alloca_uninitialized ||
109+ builtinID == Builtin::BIalloca || builtinID == Builtin::BI_alloca);
110+
111+ // Get alloca size input
112+ mlir::Value size = cgf.emitScalarExpr (e->getArg (0 ));
113+
114+ // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
115+ const TargetInfo &ti = cgf.getContext ().getTargetInfo ();
116+ const CharUnits suitableAlignmentInBytes =
117+ cgf.getContext ().toCharUnitsFromBits (ti.getSuitableAlign ());
118+
119+ // Emit the alloca op with type `u8 *` to match the semantics of
120+ // `llvm.alloca`. We later bitcast the type to `void *` to match the
121+ // semantics of C/C++
122+ // FIXME(cir): It may make sense to allow AllocaOp of type `u8` to return a
123+ // pointer of type `void *`. This will require a change to the allocaOp
124+ // verifier.
125+ CIRGenBuilderTy &builder = cgf.getBuilder ();
126+ mlir::Value allocaAddr = builder.createAlloca (
127+ cgf.getLoc (e->getSourceRange ()), builder.getUInt8PtrTy (),
128+ builder.getUInt8Ty (), " bi_alloca" , suitableAlignmentInBytes, size);
129+
130+ // Initialize the allocated buffer if required.
131+ if (builtinID != Builtin::BI__builtin_alloca_uninitialized) {
132+ // Initialize the alloca with the given size and alignment according to
133+ // the lang opts. Only the trivial non-initialization is supported for
134+ // now.
135+
136+ switch (cgf.getLangOpts ().getTrivialAutoVarInit ()) {
137+ case LangOptions::TrivialAutoVarInitKind::Uninitialized:
138+ // Nothing to initialize.
139+ break ;
140+ case LangOptions::TrivialAutoVarInitKind::Zero:
141+ case LangOptions::TrivialAutoVarInitKind::Pattern:
142+ cgf.cgm .errorNYI (" trivial auto var init" );
143+ break ;
144+ }
145+ }
146+
147+ // An alloca will always return a pointer to the alloca (stack) address
148+ // space. This address space need not be the same as the AST / Language
149+ // default (e.g. in C / C++ auto vars are in the generic address space). At
150+ // the AST level this is handled within CreateTempAlloca et al., but for the
151+ // builtin / dynamic alloca we have to handle it here.
152+
153+ if (!cir::isMatchingAddressSpace (
154+ cgf.getCIRAllocaAddressSpace (),
155+ e->getType ()->getPointeeType ().getAddressSpace ())) {
156+ cgf.cgm .errorNYI (e->getSourceRange (),
157+ " Non-default address space for alloca" );
158+ }
159+
160+ // Bitcast the alloca to the expected type.
161+ return RValue::get (builder.createBitcast (
162+ allocaAddr, builder.getVoidPtrTy (cgf.getCIRAllocaAddressSpace ())));
163+ }
164+
105165RValue CIRGenFunction::emitBuiltinExpr (const GlobalDecl &gd, unsigned builtinID,
106166 const CallExpr *e,
107167 ReturnValueSlot returnValue) {
@@ -562,61 +622,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
562622 case Builtin::BI__builtin_flt_rounds:
563623 case Builtin::BI__builtin_set_flt_rounds:
564624 case Builtin::BI__builtin_fpclassify:
625+ return errorBuiltinNYI (*this , e, builtinID);
565626 case Builtin::BIalloca:
566627 case Builtin::BI_alloca:
567628 case Builtin::BI__builtin_alloca_uninitialized:
568- case Builtin::BI__builtin_alloca: {
569- // Get alloca size input
570- mlir::Value size = emitScalarExpr (e->getArg (0 ));
571-
572- // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
573- const TargetInfo &ti = getContext ().getTargetInfo ();
574- const CharUnits suitableAlignmentInBytes =
575- getContext ().toCharUnitsFromBits (ti.getSuitableAlign ());
576-
577- // Emit the alloca op with type `u8 *` to match the semantics of
578- // `llvm.alloca`. We later bitcast the type to `void *` to match the
579- // semantics of C/C++
580- // FIXME(cir): It may make sense to allow AllocaOp of type `u8` to return a
581- // pointer of type `void *`. This will require a change to the allocaOp
582- // verifier.
583- mlir::Value allocaAddr = builder.createAlloca (
584- getLoc (e->getSourceRange ()), builder.getUInt8PtrTy (),
585- builder.getUInt8Ty (), " bi_alloca" , suitableAlignmentInBytes, size);
586-
587- // Initialize the allocated buffer if required.
588- if (builtinID != Builtin::BI__builtin_alloca_uninitialized) {
589- // Initialize the alloca with the given size and alignment according to
590- // the lang opts. Only the trivial non-initialization is supported for
591- // now.
592-
593- switch (getLangOpts ().getTrivialAutoVarInit ()) {
594- case LangOptions::TrivialAutoVarInitKind::Uninitialized:
595- // Nothing to initialize.
596- break ;
597- case LangOptions::TrivialAutoVarInitKind::Zero:
598- case LangOptions::TrivialAutoVarInitKind::Pattern:
599- cgm.errorNYI (" trivial auto var init" );
600- break ;
601- }
602- }
603-
604- // An alloca will always return a pointer to the alloca (stack) address
605- // space. This address space need not be the same as the AST / Language
606- // default (e.g. in C / C++ auto vars are in the generic address space). At
607- // the AST level this is handled within CreateTempAlloca et al., but for the
608- // builtin / dynamic alloca we have to handle it here.
609-
610- if (!cir::isMatchingAddressSpace (
611- getCIRAllocaAddressSpace (),
612- e->getType ()->getPointeeType ().getAddressSpace ())) {
613- cgm.errorNYI (e->getSourceRange (), " Non-default address space for alloca" );
614- }
615-
616- // Bitcast the alloca to the expected type.
617- return RValue::get (builder.createBitcast (
618- allocaAddr, builder.getVoidPtrTy (getCIRAllocaAddressSpace ())));
619- }
629+ case Builtin::BI__builtin_alloca:
630+ return emitBuiltinAlloca (*this , e, builtinID);
620631 case Builtin::BI__builtin_alloca_with_align_uninitialized:
621632 case Builtin::BI__builtin_alloca_with_align:
622633 case Builtin::BI__builtin_infer_alloc_token:
@@ -940,7 +951,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
940951 case Builtin::BIto_local:
941952 case Builtin::BIto_private:
942953 case Builtin::BIenqueue_kernel:
943- // however for cases where the default AS is not the Alloca AS, Tmp is
944954 case Builtin::BIget_kernel_work_group_size:
945955 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
946956 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
@@ -952,7 +962,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
952962 return errorBuiltinNYI (*this , e, builtinID);
953963 case Builtin::BI__builtin_printf:
954964 case Builtin::BIprintf:
955- break ; // Handled by library call emission.
965+ break ;
956966 case Builtin::BI__builtin_canonicalize:
957967 case Builtin::BI__builtin_canonicalizef:
958968 case Builtin::BI__builtin_canonicalizef16:
0 commit comments