This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] prevent miscompiles from select-of-div/rem transform
ClosedPublic

Authored by spatel on Feb 23 2023, 12:55 PM.

Details

Summary

This avoids the danger shown in issue #60906. There were no regression tests for these patterns, so these potential failures have been around for a long time.

We freeze the condition and preserve the optimization because getting rid of a div/rem is always a big win.

Here are a couple of examples that can be corrected by freezing the condition:
https://alive2.llvm.org/ce/z/sXHTTC

Diff Detail

Event Timeline

spatel created this revision.Feb 23 2023, 12:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 23 2023, 12:55 PM
spatel requested review of this revision.Feb 23 2023, 12:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 23 2023, 12:55 PM

We could carve out some exceptions to this bailout. For example, the transform is actually ok with udiv/urem and a common divisor because poison in the dividend would not cause immediate UB - the divisor has to be zero, and that would be UB in the original code too. That doesn't work with signed div/rem because we can choose the poison dividend to be MinSignedValue, and that overflows when divided by -1 causing UB that doesn't exist in the original code.

This makes a lot of sense to me. Should we make this patch support this case as well?

Alternatively, if you freeze the condition of the select, the transform is legal in all cases.

Alternatively, if you freeze the condition of the select, the transform is legal in all cases.

Thanks! Yes, that's the likely better fix. This transform does get rid of a div/rem, so that's a potentially big win vs. adding a freeze.

spatel updated this revision to Diff 500754.Feb 27 2023, 6:11 AM
spatel edited the summary of this revision. (Show Details)

Patch updated:
When necessary, freeze the select condition value to preserve the optimization.

aqjune added inline comments.Feb 28 2023, 4:30 AM
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
440

Should we avoid introducing freeze if MatchIsOpZero is false and the op is udiv/urem?

spatel marked an inline comment as done.Feb 28 2023, 9:11 AM
spatel added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
440

Sure, we can refine the check.

spatel updated this revision to Diff 501175.Feb 28 2023, 9:18 AM
spatel marked an inline comment as done.

Patch updated:
Add restriction to freeze creation for unsigned ops because they are easier to determine as safe.

aqjune accepted this revision.Feb 28 2023, 11:57 AM

LGTM, thanks..!

This revision is now accepted and ready to land.Feb 28 2023, 11:57 AM