diff --git a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h --- a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h +++ b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h @@ -88,10 +88,7 @@ explicit FlatAffineValueConstraints(ArrayRef avmRef); /// Creates an affine constraint system from an IntegerSet. - explicit FlatAffineValueConstraints(IntegerSet set); - - FlatAffineValueConstraints(ArrayRef avmRef, - IntegerSet set); + explicit FlatAffineValueConstraints(IntegerSet set, ValueRange operands = {}); // Construct a hyperrectangular constraint set from ValueRanges that represent // induction variables, lower and upper bounds. `ivs`, `lbs` and `ubs` are @@ -279,7 +276,7 @@ /// Returns true if an variable with the specified Value exists, false /// otherwise. - bool containsVar(Value mayBeVar) const; + bool containsVar(Value val) const; /// Swap the posA^th variable with the posB^th variable. void swapVar(unsigned posA, unsigned posB) override; diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp --- a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp @@ -150,15 +150,20 @@ } // Construct from an IntegerSet. -FlatAffineValueConstraints::FlatAffineValueConstraints(IntegerSet set) +FlatAffineValueConstraints::FlatAffineValueConstraints(IntegerSet set, + ValueRange operands) : IntegerPolyhedron(set.getNumInequalities(), set.getNumEqualities(), set.getNumDims() + set.getNumSymbols() + 1, PresburgerSpace::getSetSpace(set.getNumDims(), set.getNumSymbols(), /*numLocals=*/0)) { - - // Resize values. - values.resize(getNumDimAndSymbolVars(), std::nullopt); + // Populate values. + if (operands.empty()) { + values.resize(getNumDimAndSymbolVars(), std::nullopt); + } else { + assert(set.getNumInputs() == operands.size() && "operand count mismatch"); + values.assign(operands.begin(), operands.end()); + } // Flatten expressions and add them to the constraint system. std::vector> flatExprs; @@ -718,12 +723,14 @@ } void FlatAffineValueConstraints::addAffineIfOpDomain(AffineIfOp ifOp) { - // Create the base constraints from the integer set attached to ifOp. - FlatAffineValueConstraints cst(ifOp.getIntegerSet()); + IntegerSet set = ifOp.getIntegerSet(); + // Canonicalize set and operands to ensure unique values for + // FlatAffineValueConstraints below and for early simplification. + SmallVector operands(ifOp.getOperands()); + canonicalizeSetAndOperands(&set, &operands); - // Bind vars in the constraints to ifOp operands. - SmallVector operands = ifOp.getOperands(); - cst.setValues(0, cst.getNumDimAndSymbolVars(), operands); + // Create the base constraints from the integer set attached to ifOp. + FlatAffineValueConstraints cst(set, operands); // Merge the constraints from ifOp to the current domain. We need first merge // and align the IDs from both constraints, and then append the constraints diff --git a/mlir/test/Transforms/memref-dependence-check.mlir b/mlir/test/Transforms/memref-dependence-check.mlir --- a/mlir/test/Transforms/memref-dependence-check.mlir +++ b/mlir/test/Transforms/memref-dependence-check.mlir @@ -1080,3 +1080,21 @@ } return } + +// ----- + +func.func @affine_if_no_dependence() { + %c1 = arith.constant 1 : index + %alloc = memref.alloc() : memref<15xi1> + %true = arith.constant true + affine.store %true, %alloc[%c1] : memref<15xi1> + // expected-remark@above {{dependence from 0 to 0 at depth 1 = false}} + // expected-remark@above {{dependence from 0 to 1 at depth 1 = false}} + // This set is empty. + affine.if affine_set<(d0, d1, d2, d3) : ((d0 + 1) mod 8 >= 0, d0 * -8 >= 0)>(%c1, %c1, %c1, %c1){ + %265 = affine.load %alloc[%c1] : memref<15xi1> + // expected-remark@above {{dependence from 1 to 0 at depth 1 = false}} + // expected-remark@above {{dependence from 1 to 1 at depth 1 = false}} + } + return +}