@@ -1193,32 +1193,55 @@ bool checkErrorIfPad(Operation *op) {
1193
1193
return true ;
1194
1194
}
1195
1195
1196
- // Returns true if the operation takes no input operands, excluding attributes.
1197
- static bool isNullaryOperation (Operation *op) {
1198
- if (isa<tosa::ConstOp>(op) || isa<tosa::ConstShapeOp>(op) ||
1199
- isa<tosa::YieldOp>(op) || isa<tosa::VariableOp>(op))
1200
- return true ;
1201
- return false ;
1196
+ static bool isOpIsolatedWithinRegion (Operation *op, Region *region) {
1197
+ return llvm::all_of (op->getOperands (), [&](auto operand) {
1198
+ Region *operandRegion = operand.getParentRegion ();
1199
+ return operandRegion && region->isAncestor (operandRegion);
1200
+ });
1202
1201
}
1203
1202
1204
1203
bool checkErrorIfCondIf (Operation *op) {
1205
1204
auto ifOp = dyn_cast<tosa::IfOp>(op);
1206
1205
if (!ifOp)
1207
1206
return true ;
1208
1207
1209
- // Whether the types and shapes of operands between the input/output list and
1210
- // internal regions are validated by the operation verifier. However, with
1211
- // support for the simplified form - where redundant operand notations are
1212
- // omitted - is not conformant to the specification. According to the
1213
- // specification, all operands passed into an operation must be explicitly
1214
- // declared at each operation's structure. This code section verify that the
1215
- // operation's form complies with this requirement.
1208
+ // Currently the dialect supports declaring cond_if operations that
1209
+ // have then/else regions that reference values from outside these
1210
+ // regions. According to the specification, all values used by the
1211
+ // then/else regions must be explicitly declared within the regions.
1212
+ // Therefore we must check that the then/else regions are
1213
+ // "isolated from above", in order to be conformant to the
1214
+ // specification.
1215
+ //
1216
+ // Note: the dialect currently supports two styles of syntax for
1217
+ // declaring "cond_if" operations. We'll refer to these as follows:
1218
+ //
1219
+ // Generic:
1220
+ // %0 = "tosa.cond_if"(%arg0, %arg1, %arg2) ({
1221
+ // ^bb0(%arg3, %arg4):
1222
+ // tosa.yield %arg3
1223
+ // }, {
1224
+ // ^bb0(%arg3, %arg4):
1225
+ // tosa.yield %arg4
1226
+ // })
1227
+ //
1228
+ // Simplified:
1229
+ // %0 = tosa.cond_if %arg2 {
1230
+ // tosa.yield %arg0
1231
+ // } else {
1232
+ // tosa.yield %arg1
1233
+ // }
1234
+ //
1235
+ // Unfortunately, the simplified syntax does not encapsulate values
1236
+ // used in then/else regions (see 'simplified' example above), so it
1237
+ // must be rewritten to use the generic syntax in order to be conformant
1238
+ // to the specification.
1216
1239
1217
1240
// Returns true if the region uses no external input operands.
1218
- auto isNullaryRegion = [](Region ®ion ) -> bool {
1241
+ auto isIsolatedRegion = [](Region ®ionToCheck ) -> bool {
1219
1242
bool noLiveInValue = true ;
1220
- region .walk ([&noLiveInValue](Operation *op ) {
1221
- if (!isNullaryOperation (op )) {
1243
+ regionToCheck .walk ([&noLiveInValue, ®ionToCheck ](Operation *opInRegion ) {
1244
+ if (!isOpIsolatedWithinRegion (opInRegion, ®ionToCheck )) {
1222
1245
noLiveInValue = false ;
1223
1246
return WalkResult::interrupt ();
1224
1247
}
@@ -1227,21 +1250,18 @@ bool checkErrorIfCondIf(Operation *op) {
1227
1250
return noLiveInValue;
1228
1251
};
1229
1252
1230
- mlir::Region &thenGraph = ifOp.getThenGraph ();
1231
- mlir::Region &elseGraph = ifOp.getElseGraph ();
1232
- bool isThenGraphNullaryRegion = isNullaryRegion (thenGraph);
1233
- bool isElseGraphNullaryRegion = isNullaryRegion (elseGraph);
1234
- bool isInputListEmpty = ifOp.getInputList ().size () == 0 ;
1235
-
1236
- if ((isInputListEmpty != isThenGraphNullaryRegion) ||
1237
- (isInputListEmpty != isElseGraphNullaryRegion)) {
1253
+ auto checkIsolatedRegion = [&](Region ®ionToCheck,
1254
+ StringRef regionName) -> LogicalResult {
1255
+ if (isIsolatedRegion (regionToCheck))
1256
+ return success ();
1238
1257
op->emitOpError ()
1239
- << " the current simplified form is not strictly conformant to the "
1240
- " spec, please use the generic format \n " ;
1241
- return false ;
1242
- }
1258
+ << " is not conformant to the TOSA specification. It requires the ' "
1259
+ << regionName << " ' region is isolated from above. \n " ;
1260
+ return failure () ;
1261
+ };
1243
1262
1244
- return true ;
1263
+ return failed (checkIsolatedRegion (ifOp.getThenGraph (), " then" )) ||
1264
+ failed (checkIsolatedRegion (ifOp.getElseGraph (), " else" ));
1245
1265
}
1246
1266
1247
1267
bool checkErrorIfScatter (Operation *op) {
0 commit comments