@@ -1193,32 +1193,55 @@ bool checkErrorIfPad(Operation *op) {
11931193 return true ;
11941194}
11951195
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+ });
12021201}
12031202
12041203bool checkErrorIfCondIf (Operation *op) {
12051204 auto ifOp = dyn_cast<tosa::IfOp>(op);
12061205 if (!ifOp)
12071206 return true ;
12081207
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.
12161239
12171240 // Returns true if the region uses no external input operands.
1218- auto isNullaryRegion = [](Region ®ion ) -> bool {
1241+ auto isIsolatedRegion = [](Region ®ionToCheck ) -> bool {
12191242 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 )) {
12221245 noLiveInValue = false ;
12231246 return WalkResult::interrupt ();
12241247 }
@@ -1227,21 +1250,18 @@ bool checkErrorIfCondIf(Operation *op) {
12271250 return noLiveInValue;
12281251 };
12291252
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 ();
12381257 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+ };
12431262
1244- return true ;
1263+ return failed (checkIsolatedRegion (ifOp.getThenGraph (), " then" )) ||
1264+ failed (checkIsolatedRegion (ifOp.getElseGraph (), " else" ));
12451265}
12461266
12471267bool checkErrorIfScatter (Operation *op) {
0 commit comments