@@ -27,12 +27,22 @@ struct AffineApplyOpInterface
27
27
assert (applyOp.getAffineMap ().getNumResults () == 1 &&
28
28
" expected single result" );
29
29
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
+
30
37
// 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]));
36
46
AffineExpr bound =
37
47
expr.replaceDimsAndSymbols (dimReplacements, symReplacements);
38
48
cstr.bound (value) == bound;
@@ -92,3 +102,30 @@ void mlir::affine::registerValueBoundsOpInterfaceExternalModels(
92
102
AffineMinOp::attachInterface<AffineMinOpInterface>(*ctx);
93
103
});
94
104
}
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