@@ -27,12 +27,22 @@ struct AffineApplyOpInterface
2727 assert (applyOp.getAffineMap ().getNumResults () == 1 &&
2828 " expected single result" );
2929
30+ // Fully compose this affine.apply with other ops because the folding logic
31+ // can see opportunities for simplifying the affine map that
32+ // `FlatLinearConstraints` can currently not see.
33+ AffineMap map = applyOp.getAffineMap ();
34+ SmallVector<Value> operands = llvm::to_vector (applyOp.getOperands ());
35+ fullyComposeAffineMapAndOperands (&map, &operands);
36+
3037 // Align affine map result with dims/symbols in the constraint set.
31- AffineExpr expr = applyOp.getAffineMap ().getResult (0 );
32- SmallVector<AffineExpr> dimReplacements = llvm::to_vector (llvm::map_range (
33- applyOp.getDimOperands (), [&](Value v) { return cstr.getExpr (v); }));
34- SmallVector<AffineExpr> symReplacements = llvm::to_vector (llvm::map_range (
35- applyOp.getSymbolOperands (), [&](Value v) { return cstr.getExpr (v); }));
38+ AffineExpr expr = map.getResult (0 );
39+ SmallVector<AffineExpr> dimReplacements, symReplacements;
40+ for (int64_t i = 0 , e = map.getNumDims (); i < e; ++i)
41+ dimReplacements.push_back (cstr.getExpr (operands[i]));
42+ for (int64_t i = map.getNumDims (),
43+ e = map.getNumDims () + map.getNumSymbols ();
44+ i < e; ++i)
45+ symReplacements.push_back (cstr.getExpr (operands[i]));
3646 AffineExpr bound =
3747 expr.replaceDimsAndSymbols (dimReplacements, symReplacements);
3848 cstr.bound (value) == bound;
@@ -92,3 +102,30 @@ void mlir::affine::registerValueBoundsOpInterfaceExternalModels(
92102 AffineMinOp::attachInterface<AffineMinOpInterface>(*ctx);
93103 });
94104}
105+
106+ FailureOr<bool > mlir::affine::fullyComposeAndCheckIfEqual (Value value1,
107+ Value value2) {
108+ assert (value1.getType ().isIndex () && " expected index type" );
109+ assert (value2.getType ().isIndex () && " expected index type" );
110+
111+ // Subtract the two values/dimensions from each other. If the result is 0,
112+ // both are equal.
113+ Builder b (value1.getContext ());
114+ AffineMap map = AffineMap::get (/* dimCount=*/ 2 , /* symbolCount=*/ 0 ,
115+ b.getAffineDimExpr (0 ) - b.getAffineDimExpr (1 ));
116+ // Fully compose the affine map with other ops because the folding logic
117+ // can see opportunities for simplifying the affine map that
118+ // `FlatLinearConstraints` can currently not see.
119+ SmallVector<Value> mapOperands;
120+ mapOperands.push_back (value1);
121+ mapOperands.push_back (value2);
122+ affine::fullyComposeAffineMapAndOperands (&map, &mapOperands);
123+ ValueDimList valueDims;
124+ for (Value v : mapOperands)
125+ valueDims.push_back ({v, std::nullopt });
126+ FailureOr<int64_t > bound = ValueBoundsConstraintSet::computeConstantBound (
127+ presburger::BoundType::EQ, map, valueDims);
128+ if (failed (bound))
129+ return failure ();
130+ return *bound == 0 ;
131+ }
0 commit comments