@@ -793,16 +793,45 @@ static AffineExpr simplifyAdd(AffineExpr lhs, AffineExpr rhs) {
793793 return nullptr ;
794794}
795795
796+ // / Get the canonical order of two commutative exprs arguments.
797+ static std::pair<AffineExpr, AffineExpr>
798+ orderCommutativeArgs (AffineExpr expr1, AffineExpr expr2) {
799+ auto sym1 = dyn_cast<AffineSymbolExpr>(expr1);
800+ auto sym2 = dyn_cast<AffineSymbolExpr>(expr2);
801+ // Try to order by symbol/dim position first.
802+ if (sym1 && sym2)
803+ return sym1.getPosition () < sym2.getPosition () ? std::pair{expr1, expr2}
804+ : std::pair{expr2, expr1};
805+
806+ auto dim1 = dyn_cast<AffineDimExpr>(expr1);
807+ auto dim2 = dyn_cast<AffineDimExpr>(expr2);
808+ if (dim1 && dim2)
809+ return dim1.getPosition () < dim2.getPosition () ? std::pair{expr1, expr2}
810+ : std::pair{expr2, expr1};
811+
812+ // Put dims before symbols.
813+ if (dim1 && sym2)
814+ return {dim1, sym2};
815+
816+ if (sym1 && dim2)
817+ return {dim2, sym1};
818+
819+ // Otherwise, keep original order.
820+ return {expr1, expr2};
821+ }
822+
796823AffineExpr AffineExpr::operator +(int64_t v) const {
797824 return *this + getAffineConstantExpr (v, getContext ());
798825}
799826AffineExpr AffineExpr::operator +(AffineExpr other) const {
800827 if (auto simplified = simplifyAdd (*this , other))
801828 return simplified;
802829
830+ auto [lhs, rhs] = orderCommutativeArgs (*this , other);
831+
803832 StorageUniquer &uniquer = getContext ()->getAffineUniquer ();
804833 return uniquer.get <AffineBinaryOpExprStorage>(
805- /* initFn=*/ {}, static_cast <unsigned >(AffineExprKind::Add), * this , other );
834+ /* initFn=*/ {}, static_cast <unsigned >(AffineExprKind::Add), lhs, rhs );
806835}
807836
808837// / Simplify a multiply expression. Return nullptr if it can't be simplified.
@@ -865,9 +894,11 @@ AffineExpr AffineExpr::operator*(AffineExpr other) const {
865894 if (auto simplified = simplifyMul (*this , other))
866895 return simplified;
867896
897+ auto [lhs, rhs] = orderCommutativeArgs (*this , other);
898+
868899 StorageUniquer &uniquer = getContext ()->getAffineUniquer ();
869900 return uniquer.get <AffineBinaryOpExprStorage>(
870- /* initFn=*/ {}, static_cast <unsigned >(AffineExprKind::Mul), * this , other );
901+ /* initFn=*/ {}, static_cast <unsigned >(AffineExprKind::Mul), lhs, rhs );
871902}
872903
873904// Unary minus, delegate to operator*.
0 commit comments