diff --git a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp --- a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp +++ b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp @@ -14,7 +14,7 @@ #include "mlir/Dialect/Affine/Analysis/Utils.h" #include "mlir/Dialect/Affine/IR/AffineOps.h" -#include "mlir/Dialect/Affine/Utils.h" +#include "mlir/Dialect/Affine/LoopUtils.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/IntegerSet.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" @@ -83,7 +83,12 @@ } void SimplifyAffineStructures::runOnOperation() { - auto func = getOperation(); + func::FuncOp func = getOperation(); + + // Promote any single iteration affine loops. This relies on an + // analysis utility, and is thus not part of canonicalization. + func.walk([&](AffineForOp forOp) { (void)promoteIfSingleIteration(forOp); }); + simplifiedAttributes.clear(); RewritePatternSet patterns(func.getContext()); AffineApplyOp::getCanonicalizationPatterns(patterns, func.getContext()); diff --git a/mlir/test/Dialect/Affine/simplify-structures.mlir b/mlir/test/Dialect/Affine/simplify-structures.mlir --- a/mlir/test/Dialect/Affine/simplify-structures.mlir +++ b/mlir/test/Dialect/Affine/simplify-structures.mlir @@ -232,6 +232,16 @@ return } +// CHECK-LABEL: func.func @promote_single_iter +func.func @promote_single_iter(%N: index) { + // CHECK-NEXT: test.foo + // CHECK-NEXT: return + affine.for %i = %N to affine_map<(d0) -> (d0 + 1)>(%N) { + "test.foo"() : () -> () + } + return +} + // ----- // An external function that we will use in bodies to avoid DCE.