This is an archive of the discontinued LLVM Phabricator instance.

[mlir] fix wrong symbol order in AffineApplyNormalizer
ClosedPublic

Authored by ftynse on Feb 27 2020, 5:46 AM.

Details

Summary

AffineApplyNormalizer provides common logic for folding affine maps that appear
in affine.apply into other affine operations that use the result of said
affine.apply. In the process, affine maps of both operations are composed.
During the composition A.compose(B) the symbols from the map A are placed
before those of the map B in a single concatenated symbol list. However,
AffineApplyNormalizer was ordering the operands of the operation being
normalized by iteratively appending the symbols into a single list accoridng to
the operand order, regardless of whether these operands are symbols of the
current operation or of the map that is being folded into it. This could lead
to wrong order of symbols and, when the symbols were bound to constant values,
to visibly incorrect folding of constants into affine maps as reported in
PR45031. Make sure symbols operands to the current operation are always placed
before symbols coming from the folded maps.

Update the test that was exercising the incorrect folder behavior. For some
reason, the order of symbol operands was swapped in the test input compared to
the previous operations, making it easy to assume the correct maps were
produced whereas they were swapping the symbols back due to the problem
described above.

Closes https://bugs.llvm.org/show_bug.cgi?id=45031

Diff Detail

Event Timeline

ftynse created this revision.Feb 27 2020, 5:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 27 2020, 5:46 AM
nicolasvasilache accepted this revision.Feb 27 2020, 5:56 AM

Thanks for tracking this down Alex!

Note that a lot of the complexity of AffineApplyNormalizer comes from its supporting chain of affine applies and I strongly advocated for being unnecessary cognitive overhead.
We had a window of opportunity to clean all this up about 1 year ago but it got a lot of pushback for very bad reasons (e.g. a few tests with single affine_apply and composed maps would have been more complex).
Are we now in a position were we could say that chains of ops with affine map composition are outlawed so we could simplify this logic?

This revision is now accepted and ready to land.Feb 27 2020, 5:56 AM

Well actually the example you added is affine.min(affine.apply()) and goes against what I wrote above and would ideally have been composed in the first place.

I'd recommend we start putting verifiers that disallow such chains everywhere and simplify the logic, but I have not followed deeply what new assumptions have crept inside affine.

I only replicated the IR that exhibited the buggy behavior. Same problem would have happened with affine.load(affine.apply) or any other composition. Same problem would have also happened if parts of this code were used for folding-on-construction.

herhut accepted this revision.Feb 27 2020, 6:15 AM

Thanks for fixing this!

Nit: accoridng in the CL description.

Regarding Nicholas' comment: By such chains, you mean chains of affine.apply? Or also the cases of an affine.min on an affine.apply?

bondhugula added a subscriber: bondhugula.EditedFeb 27 2020, 8:00 AM

I only replicated the IR that exhibited the buggy behavior. Same problem would have happened with affine.load(affine.apply) or any other composition. Same problem would have also happened if parts of this code were used for folding-on-construction.

+1 to @ftynse. Absolutely! One needs in-memory composition and compose/fold in by construction - both for creating IR and for analysis. Making and pushing IR design decisions because there is buggy code based on incorrect assumptions (along with matching incorrect test cases) sounds hilarious to me! :-) And in any case, the fundamental need for compositions of maps with operands isn't avoided by just restricting what the printed/parsed IR represents.

Making and pushing IR design decisions because there is buggy code based on incorrect assumptions (along with matching incorrect test cases) sounds hilarious to me! :-)

I think you misspelled "unnecessary cognitive overhead" :)
In any case I don't see what convoluted logic results in the implication bug => IR design decision.

The non-fallacious logic is IR design => unnecessary cognitive overhead => consider changing IR design :)
There are many places in affine that have been guilty of that historically and some are remaining today.
This particular one has been around for a lot of time.

The bug fix is one thing that goes in regardless.

Adding others to visibility: @albertcohen @andydavis1

This revision was automatically updated to reflect the committed changes.