@@ -149,6 +149,57 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
149149 emitVAEnd (emitVAListRef (e->getArg (0 )).getPointer ());
150150 return {};
151151
152+ case Builtin::BIalloca:
153+ case Builtin::BI_alloca:
154+ case Builtin::BI__builtin_alloca_uninitialized:
155+ case Builtin::BI__builtin_alloca: {
156+ // Get alloca size input
157+ mlir::Value size = emitScalarExpr (e->getArg (0 ));
158+
159+ // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
160+ const TargetInfo &ti = getContext ().getTargetInfo ();
161+ const CharUnits suitableAlignmentInBytes =
162+ getContext ().toCharUnitsFromBits (ti.getSuitableAlign ());
163+
164+ // Emit the alloca op with type `u8 *` to match the semantics of
165+ // `llvm.alloca`. We later bitcast the type to `void *` to match the
166+ // semantics of C/C++
167+ // FIXME(cir): It may make sense to allow AllocaOp of type `u8` to return a
168+ // pointer of type `void *`. This will require a change to the allocaOp
169+ // verifier.
170+ mlir::Value allocaAddr = builder.createAlloca (
171+ getLoc (e->getSourceRange ()), builder.getUInt8PtrTy (),
172+ builder.getUInt8Ty (), " bi_alloca" , suitableAlignmentInBytes, size);
173+
174+ // Initialize the allocated buffer if required.
175+ if (builtinID != Builtin::BI__builtin_alloca_uninitialized) {
176+ // Initialize the alloca with the given size and alignment according to
177+ // the lang opts. Only the trivial non-initialization is supported for
178+ // now.
179+
180+ switch (getLangOpts ().getTrivialAutoVarInit ()) {
181+ case LangOptions::TrivialAutoVarInitKind::Uninitialized:
182+ // Nothing to initialize.
183+ break ;
184+ case LangOptions::TrivialAutoVarInitKind::Zero:
185+ case LangOptions::TrivialAutoVarInitKind::Pattern:
186+ cgm.errorNYI (" trivial auto var init" );
187+ break ;
188+ }
189+ }
190+
191+ // An alloca will always return a pointer to the alloca (stack) address
192+ // space. This address space need not be the same as the AST / Language
193+ // default (e.g. in C / C++ auto vars are in the generic address space). At
194+ // the AST level this is handled within CreateTempAlloca et al., but for the
195+ // builtin / dynamic alloca we have to handle it here.
196+ assert (!cir::MissingFeatures::addressSpace ());
197+
198+ // Bitcast the alloca to the expected type.
199+ return RValue::get (
200+ builder.createBitcast (allocaAddr, builder.getVoidPtrTy ()));
201+ }
202+
152203 case Builtin::BIfabs:
153204 case Builtin::BIfabsf:
154205 case Builtin::BIfabsl:
0 commit comments