@@ -117,23 +117,29 @@ concatAffs(isl::space space, T op, bool allowMin, bool allowMax) {
117
117
/*
118
118
* Convert Halide binary expression "op" into an isl affine function by
119
119
* converting its LHS and RHS into affs and combining them with "combine"
120
- * into a single expression. LHS and RHS are expected to only produce a single
121
- * expression.
120
+ * into a single expression. LHS and RHS are expected to only produce at most
121
+ * one expression. If either of them produces zero expressions, meaning the
122
+ * bound is not affine, return an empty vector. Otherwise return a vector with
123
+ * a single expression that is the result of applying LHS.combine(RHS).
122
124
* This is intended for use with operations other than Min/Max that do not
123
125
* commute nicely in bounds, for example
124
126
* x < a + max(b,c) NOT <=> x < a + b AND x < a + c for negative values.
125
127
*/
126
128
template <typename T>
127
- inline isl::aff combineSingleAffs (
129
+ inline std::vector< isl::aff> combineSingleAffs (
128
130
isl::space space,
129
131
T op,
130
132
isl::aff (isl::aff::*combine)(isl::aff) const ) {
131
133
auto left = makeIslAffBoundsFromExpr (space, op->a , false , false );
132
134
auto right = makeIslAffBoundsFromExpr (space, op->b , false , false );
133
- CHECK_EQ (left.size (), 1u );
134
- CHECK_EQ (right.size (), 1u );
135
+ CHECK_LE (left.size (), 1u );
136
+ CHECK_LE (right.size (), 1u );
137
+
138
+ if (left.size () == 0 || right.size () == 0 ) {
139
+ return {};
140
+ }
135
141
136
- return (left[0 ].*combine)(right[0 ]);
142
+ return { (left[0 ].*combine)(right[0 ])} ;
137
143
}
138
144
139
145
} // end namespace
@@ -183,13 +189,13 @@ std::vector<isl::aff> makeIslAffBoundsFromExpr(
183
189
} else if (maxOp != nullptr && allowMax) {
184
190
return concatAffs (space, maxOp, allowMin, allowMax);
185
191
} else if (const Add* op = e.as <Add>()) {
186
- return { combineSingleAffs (space, op, &isl::aff::add)} ;
192
+ return combineSingleAffs (space, op, &isl::aff::add);
187
193
} else if (const Sub* op = e.as <Sub>()) {
188
- return { combineSingleAffs (space, op, &isl::aff::sub)} ;
194
+ return combineSingleAffs (space, op, &isl::aff::sub);
189
195
} else if (const Mul* op = e.as <Mul>()) {
190
- return { combineSingleAffs (space, op, &isl::aff::mul)} ;
196
+ return combineSingleAffs (space, op, &isl::aff::mul);
191
197
} else if (const Div* op = e.as <Div>()) {
192
- return { combineSingleAffs (space, op, &isl::aff::div)} ;
198
+ return combineSingleAffs (space, op, &isl::aff::div);
193
199
} else if (const Mod* op = e.as <Mod>()) {
194
200
std::vector<isl::aff> result;
195
201
// We cannot span multiple constraints if a modulo operation is involved.
0 commit comments