@@ -381,9 +381,10 @@ static void dumpModuleOnFailure(ModuleOp module, StringRef phase)
381381 // inconsistent, so we skip it.
382382}
383383
384- static void normalizeFuncTerminators (mlir::func::FuncOp funcOp)
384+ static bool normalizeFuncTerminators (mlir::func::FuncOp funcOp)
385385{
386386 mlir::IRRewriter rewriter (funcOp.getContext ());
387+ bool hadMalformedBlock = false ;
387388 for (Block &block : funcOp.getBody ())
388389 {
389390 Operation *terminator = nullptr ;
@@ -397,16 +398,30 @@ static void normalizeFuncTerminators(mlir::func::FuncOp funcOp)
397398 }
398399 if (!terminator)
399400 {
401+ hadMalformedBlock = true ;
402+ llvm::errs () << " [OraToSIR] ERROR: Missing terminator in function "
403+ << funcOp.getName () << " at " << block.getParent ()->getLoc () << " \n " ;
400404 rewriter.setInsertionPointToEnd (&block);
401405 rewriter.create <sir::InvalidOp>(funcOp.getLoc ());
402406 continue ;
403407 }
404408 if (terminator->getNextNode ())
405409 {
410+ hadMalformedBlock = true ;
406411 llvm::errs () << " [OraToSIR] ERROR: Terminator has trailing ops in function "
407412 << funcOp.getName () << " at " << terminator->getLoc () << " \n " ;
413+ // Keep IR valid for downstream passes by dropping unreachable ops
414+ // that were left after a terminator.
415+ Operation *extra = terminator->getNextNode ();
416+ while (extra)
417+ {
418+ Operation *next = extra->getNextNode ();
419+ extra->erase ();
420+ extra = next;
421+ }
408422 }
409423 }
424+ return hadMalformedBlock;
410425}
411426
412427static LogicalResult eraseRefinements (ModuleOp module )
@@ -813,6 +828,7 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
813828 patterns.add <ConvertTStoreOp>(typeConverter, ctx);
814829 patterns.add <ConvertMapGetOp>(typeConverter, ctx, PatternBenefit (5 ));
815830 patterns.add <ConvertMapStoreOp>(typeConverter, ctx, PatternBenefit (5 ));
831+ patterns.add <ConvertTensorInsertOp>(typeConverter, ctx);
816832 patterns.add <ConvertTensorExtractOp>(typeConverter, ctx);
817833 patterns.add <ConvertTensorDimOp>(typeConverter, ctx);
818834 }
@@ -872,7 +888,7 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
872888 if (enable_storage)
873889 {
874890 // Force storage-related tensor ops to lower when arrays/maps are enabled.
875- target.addIllegalOp <mlir::tensor::ExtractOp, mlir::tensor::DimOp>();
891+ target.addIllegalOp <mlir::tensor::InsertOp, mlir::tensor:: ExtractOp, mlir::tensor::DimOp>();
876892 }
877893 target.addIllegalOp <ora::ContractOp>();
878894 target.addLegalOp <ora::ReturnOp>();
@@ -1077,9 +1093,12 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
10771093 phase2Target.addLegalDialect <mlir::scf::SCFDialect>();
10781094 phase2Target.addLegalDialect <mlir::arith::ArithDialect>();
10791095 phase2Target.addLegalOp <ora::ReturnOp>();
1080- phase2Target.addIllegalOp <ora::ErrorIsErrorOp>();
1081- phase2Target.addIllegalOp <ora::ErrorUnwrapOp>();
1082- phase2Target.addIllegalOp <ora::ErrorGetErrorOp>();
1096+ // Defer ora.error.is_error lowering to phase 2b. Some wide error-union
1097+ // forms are normalized there after additional rewrites.
1098+ phase2Target.addLegalOp <ora::ErrorIsErrorOp>();
1099+ // Defer scalar error accessors to phase 2b together with CFG lowering.
1100+ phase2Target.addLegalOp <ora::ErrorUnwrapOp>();
1101+ phase2Target.addLegalOp <ora::ErrorGetErrorOp>();
10831102 phase2Target.addLegalOp <ora::ErrorOkOp>();
10841103 phase2Target.addLegalOp <ora::ErrorErrOp>();
10851104 phase2Target.addLegalOp <ora::IfOp>();
@@ -1305,6 +1324,7 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
13051324 phase4Patterns.add <ConvertArithIndexCastUIOp>(typeConverter, ctx);
13061325 phase4Patterns.add <ConvertArithIndexCastOp>(typeConverter, ctx);
13071326 phase4Patterns.add <ConvertArithTruncIOp>(typeConverter, ctx);
1327+ phase4Patterns.add <ConvertTensorInsertOp>(typeConverter, ctx);
13081328 phase4Patterns.add <ConvertTensorExtractOp>(typeConverter, ctx);
13091329 phase4Patterns.add <ConvertTensorDimOp>(typeConverter, ctx);
13101330 phase4Patterns.add <ConvertBaseToRefinementOp>(typeConverter, ctx);
@@ -1506,18 +1526,34 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
15061526 return ;
15071527 }
15081528
1509- // Debug: dump final module.
1529+ // Normalize malformed blocks before any final printing/validation so we
1530+ // fail cleanly instead of reaching MLIR internals with invalid CFG.
1531+ bool hadMalformedTerminatorBlocks = false ;
1532+ module .walk ([&](mlir::func::FuncOp funcOp) {
1533+ hadMalformedTerminatorBlocks = normalizeFuncTerminators (funcOp) || hadMalformedTerminatorBlocks;
1534+ });
1535+ if (hadMalformedTerminatorBlocks)
1536+ {
1537+ module .emitError (" [OraToSIR] malformed CFG: missing terminator or trailing ops after terminator" );
1538+ signalPassFailure ();
1539+ return ;
1540+ }
1541+
1542+ // Avoid in-pass full module dump here: if IR is structurally damaged,
1543+ // pretty-print traversal itself can crash before we report a clean
1544+ // diagnostic. The CLI still prints SIR MLIR after successful conversion.
15101545 if (mlir::ora::isDebugEnabled ())
15111546 {
1512- llvm::errs () << " \n //===----------------------------------------------------------------------===//\n " ;
1513- llvm::errs () << " // SIR MLIR (after Phase4)\n " ;
1514- llvm::errs () << " //===----------------------------------------------------------------------===//\n\n " ;
1515- module .print (llvm::errs ());
1516- llvm::errs () << " \n " ;
1547+ llvm::errs () << " [OraToSIR] Post-Phase4: internal module dump skipped\n " ;
15171548 llvm::errs ().flush ();
15181549 }
15191550
15201551 // Extra guard: detect any remaining unrealized casts by name.
1552+ if (mlir::ora::isDebugEnabled ())
1553+ {
1554+ llvm::errs () << " [OraToSIR] Post-Phase4: name-scan start\n " ;
1555+ llvm::errs ().flush ();
1556+ }
15211557 int64_t unrealizedByName = 0 ;
15221558 module .walk ([&](Operation *op) {
15231559 if (op->getName ().getStringRef () == " builtin.unrealized_conversion_cast" )
@@ -1538,6 +1574,7 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
15381574 });
15391575 if (mlir::ora::isDebugEnabled ())
15401576 {
1577+ llvm::errs () << " [OraToSIR] Post-Phase4: name-scan done (count=" << unrealizedByName << " )\n " ;
15411578 llvm::errs ().flush ();
15421579 }
15431580 if (unrealizedByName > 0 )
@@ -1550,6 +1587,11 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
15501587 }
15511588
15521589 // Guard: fail if any ops remain that should have been lowered by this stage.
1590+ if (mlir::ora::isDebugEnabled ())
1591+ {
1592+ llvm::errs () << " [OraToSIR] Post-Phase4: illegal-op scan start\n " ;
1593+ llvm::errs ().flush ();
1594+ }
15531595 bool illegalFound = false ;
15541596 module .walk ([&](Operation *op)
15551597 {
@@ -1582,11 +1624,17 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
15821624 signalPassFailure ();
15831625 return ;
15841626 }
1627+ if (mlir::ora::isDebugEnabled ())
1628+ {
1629+ llvm::errs () << " [OraToSIR] Post-Phase4: illegal-op scan done\n " ;
1630+ llvm::errs ().flush ();
1631+ }
15851632
1586- // Guard: ensure every block in every function has a terminator.
1587- module .walk ([&](mlir::func::FuncOp funcOp)
1588- { normalizeFuncTerminators (funcOp); });
1589-
1633+ if (mlir::ora::isDebugEnabled ())
1634+ {
1635+ llvm::errs () << " [OraToSIR] Post-Phase4: terminator scan start\n " ;
1636+ llvm::errs ().flush ();
1637+ }
15901638 bool missingTerminator = false ;
15911639 module .walk ([&](mlir::func::FuncOp funcOp)
15921640 {
@@ -1596,8 +1644,6 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
15961644 {
15971645 llvm::errs () << " [OraToSIR] ERROR: Missing terminator in function "
15981646 << funcOp.getName () << " at " << funcOp.getLoc () << " \n " ;
1599- llvm::errs () << " [OraToSIR] Block contents:\n " ;
1600- block.dump ();
16011647 missingTerminator = true ;
16021648 }
16031649 } });
@@ -1607,28 +1653,55 @@ class OraToSIRPass : public PassWrapper<OraToSIRPass, OperationPass<ModuleOp>>
16071653 signalPassFailure ();
16081654 return ;
16091655 }
1656+ if (mlir::ora::isDebugEnabled ())
1657+ {
1658+ llvm::errs () << " [OraToSIR] Post-Phase4: terminator scan done\n " ;
1659+ llvm::errs ().flush ();
1660+ }
16101661
16111662 {
1612- RewritePatternSet cleanupPatterns (ctx);
1613- cleanupPatterns.add <FoldRedundantBitcastOp>(ctx);
1614- cleanupPatterns.add <FoldEqSameOp>(ctx);
1615- cleanupPatterns.add <FoldEqConstOp>(ctx);
1616- cleanupPatterns.add <FoldIsZeroConstOp>(ctx);
1617- cleanupPatterns.add <FoldCondBrSameDestOp>(ctx);
1618- cleanupPatterns.add <NormalizeCondBrOperandsOp>(ctx);
1619- cleanupPatterns.add <FoldCondBrDoubleIsZeroOp>(ctx);
1620- cleanupPatterns.add <FoldCondBrConstOp>(ctx);
1621- cleanupPatterns.add <FoldBrToBrOp>(ctx);
1622- (void )applyPatternsGreedily (module , std::move (cleanupPatterns));
1663+ if (mlir::ora::isDebugEnabled ())
1664+ {
1665+ llvm::errs () << " [OraToSIR] Post-Phase4: greedy cleanup start\n " ;
1666+ llvm::errs ().flush ();
1667+ }
1668+ // Temporarily disabled: greedy cleanup has been causing crashes in
1669+ // some converted loop CFGs. Keep conversion robust first.
1670+ // RewritePatternSet cleanupPatterns(ctx);
1671+ // cleanupPatterns.add<FoldRedundantBitcastOp>(ctx);
1672+ // cleanupPatterns.add<FoldEqSameOp>(ctx);
1673+ // cleanupPatterns.add<FoldEqConstOp>(ctx);
1674+ // cleanupPatterns.add<FoldIsZeroConstOp>(ctx);
1675+ // cleanupPatterns.add<FoldCondBrSameDestOp>(ctx);
1676+ // cleanupPatterns.add<NormalizeCondBrOperandsOp>(ctx);
1677+ // cleanupPatterns.add<FoldCondBrDoubleIsZeroOp>(ctx);
1678+ // cleanupPatterns.add<FoldCondBrConstOp>(ctx);
1679+ // cleanupPatterns.add<FoldBrToBrOp>(ctx);
1680+ // (void)applyPatternsGreedily(module, std::move(cleanupPatterns));
1681+ if (mlir::ora::isDebugEnabled ())
1682+ {
1683+ llvm::errs () << " [OraToSIR] Post-Phase4: greedy cleanup done\n " ;
1684+ llvm::errs ().flush ();
1685+ }
16231686 }
16241687
16251688 // Remove gas_cost attributes from all operations (Ora MLIR specific, not SIR)
1689+ if (mlir::ora::isDebugEnabled ())
1690+ {
1691+ llvm::errs () << " [OraToSIR] Post-Phase4: gas attribute cleanup start\n " ;
1692+ llvm::errs ().flush ();
1693+ }
16261694 module .walk ([&](Operation *op)
16271695 {
16281696 if (op->hasAttr (" gas_cost" ))
16291697 {
16301698 op->removeAttr (" gas_cost" );
16311699 } });
1700+ if (mlir::ora::isDebugEnabled ())
1701+ {
1702+ llvm::errs () << " [OraToSIR] Post-Phase4: gas attribute cleanup done\n " ;
1703+ llvm::errs ().flush ();
1704+ }
16321705
16331706 // Check what Ora ops remain (should be none)
16341707 module .walk ([&](Operation *op)
0 commit comments