@@ -257,6 +257,23 @@ Value emitAddressAtOffset(LowerFunction &LF, Value addr,
257
257
return addr;
258
258
}
259
259
260
+ mlir::cir::AllocaOp findAlloca (Operation *op) {
261
+ if (!op)
262
+ return {};
263
+
264
+ if (auto al = dyn_cast<mlir::cir::AllocaOp>(op)) {
265
+ return al;
266
+ } else if (auto ret = dyn_cast<mlir::cir::ReturnOp>(op)) {
267
+ auto vals = ret.getInput ();
268
+ if (vals.size () == 1 )
269
+ return findAlloca (vals[0 ].getDefiningOp ());
270
+ } else if (auto load = dyn_cast<mlir::cir::LoadOp>(op)) {
271
+ return findAlloca (load.getAddr ().getDefiningOp ());
272
+ }
273
+
274
+ return {};
275
+ }
276
+
260
277
// / After the calling convention is lowered, an ABI-agnostic type might have to
261
278
// / be loaded back to its ABI-aware couterpart so it may be returned. If they
262
279
// / differ, we have to do a coerced load. A coerced load, which means to load a
@@ -305,6 +322,31 @@ Value castReturnValue(Value Src, Type Ty, LowerFunction &LF) {
305
322
return LF.getRewriter ().create <LoadOp>(Src.getLoc (), Cast);
306
323
}
307
324
325
+ // Otherwise do coercion through memory.
326
+ if (auto addr = findAlloca (Src.getDefiningOp ())) {
327
+ auto &rewriter = LF.getRewriter ();
328
+ auto *ctxt = LF.LM .getMLIRContext ();
329
+ auto ptrTy = PointerType::get (ctxt, Ty);
330
+ auto voidPtr = PointerType::get (ctxt, mlir::cir::VoidType::get (ctxt));
331
+
332
+ // insert alloca near the previuos one
333
+ auto point = rewriter.saveInsertionPoint ();
334
+ rewriter.setInsertionPointAfter (addr);
335
+ auto align = LF.LM .getDataLayout ().getABITypeAlign (Ty);
336
+ auto alignAttr = rewriter.getI64IntegerAttr (align.value ());
337
+ auto tmp =
338
+ rewriter.create <AllocaOp>(Src.getLoc (), ptrTy, Ty, " tmp" , alignAttr);
339
+ rewriter.restoreInsertionPoint (point);
340
+
341
+ auto srcVoidPtr = createBitcast (addr, voidPtr, LF);
342
+ auto dstVoidPtr = createBitcast (tmp, voidPtr, LF);
343
+ auto i64Ty = IntType::get (ctxt, 64 , false );
344
+ auto len = rewriter.create <ConstantOp>(
345
+ Src.getLoc (), IntAttr::get (i64Ty, SrcSize.getFixedValue ()));
346
+ rewriter.create <MemCpyOp>(Src.getLoc (), dstVoidPtr, srcVoidPtr, len);
347
+ return rewriter.create <LoadOp>(Src.getLoc (), tmp.getResult ());
348
+ }
349
+
308
350
cir_cconv_unreachable (" NYI" );
309
351
}
310
352
@@ -532,23 +574,6 @@ LowerFunction::buildFunctionProlog(const LowerFunctionInfo &FI, FuncOp Fn,
532
574
return success ();
533
575
}
534
576
535
- mlir::cir::AllocaOp findAlloca (Operation *op) {
536
- if (!op)
537
- return {};
538
-
539
- if (auto al = dyn_cast<mlir::cir::AllocaOp>(op)) {
540
- return al;
541
- } else if (auto ret = dyn_cast<mlir::cir::ReturnOp>(op)) {
542
- auto vals = ret.getInput ();
543
- if (vals.size () == 1 )
544
- return findAlloca (vals[0 ].getDefiningOp ());
545
- } else if (auto load = dyn_cast<mlir::cir::LoadOp>(op)) {
546
- return findAlloca (load.getAddr ().getDefiningOp ());
547
- }
548
-
549
- return {};
550
- }
551
-
552
577
LogicalResult LowerFunction::buildFunctionEpilog (const LowerFunctionInfo &FI) {
553
578
// NOTE(cir): no-return, naked, and no result functions should be handled in
554
579
// CIRGen.
0 commit comments