This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Do not combine atomic and non-atomic loads.
ClosedPublic

Authored by rickyz on Dec 5 2021, 6:05 AM.

Details

Summary

Before this change, InstCombine was willing to fold atomic and
non-atomic loads through a PHI node as long as the first PHI argument
is not an atomic load. The combined load would be non-atomic, which is
incorrect.

Fix this by only combining the loads in a PHI node when all of the
arguments are non-atomic loads.

Thanks to Eli Friedman for pointing out the bug at
https://github.com/llvm/llvm-project/issues/50777#issuecomment-981045342!

Fixes PR51435.

Diff Detail

Event Timeline

rickyz created this revision.Dec 5 2021, 6:05 AM
rickyz requested review of this revision.Dec 5 2021, 6:05 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 5 2021, 6:05 AM
xgupta added a subscriber: xgupta.Dec 5 2021, 6:47 AM
rickyz edited the summary of this revision. (Show Details)Dec 17 2021, 6:25 PM
rickyz added reviewers: spatel, nikic.

Can we reduce the test to something like this and add it to the file where this transform is tested more generally (llvm/test/Transforms/InstCombine/phi.ll?):

define i32 @PR51435(i32* %ptr, i32* %atomic_ptr, i1 %c) {
entry:
  %x = load i32, i32* %ptr, align 4
  br i1 %c, label %if, label %end

if:
  %y = load atomic i32, i32* %atomic_ptr acquire, align 4
  br label %end

end:
  %cond = phi i32 [ %x, %entry ], [ %y, %if ]
  ret i32 %cond
}
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
663 ↗(On Diff #391907)

To conform with current coding standards, this should be "IsAtomic". Fix the existing code as an NFC pre-commit?

rickyz updated this revision to Diff 395600.Dec 20 2021, 10:49 PM
rickyz marked an inline comment as done.

Respond to comments.

Thanks for the reduced test case - I verified that it fails before this change and passes after.

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
663 ↗(On Diff #391907)

I went through the existing variables violating the coding standards and fixed them - most of them were loop iterators that I converted to range for loops. That change is unfortunately a little larger than I'd hoped - I split those changes into D116086.

nikic added inline comments.Dec 21 2021, 12:01 AM
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
699 ↗(On Diff #395600)

I think you'd be better of just bailing on LI->isAtomic() here, just as the check on the initial load does. IsAtomic is always false here, and if that weren't the case, then this check would be insufficient, because it conflates all types of atomic loads, which might have different ordering or sync scope.

rickyz updated this revision to Diff 395617.Dec 21 2021, 1:03 AM
rickyz marked an inline comment as done.

Make it clearer that we give up immediately on encountering an atomic load.

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
699 ↗(On Diff #395600)

Agreed, thanks!

spatel accepted this revision.Dec 21 2021, 8:28 AM

LGTM. We could move some of the cosmetic diffs ("const" etc) into D116086 or another pre-commit, but this seems fine too.

llvm/test/Transforms/InstCombine/phi.ll
550–551

Please pre-commit this test to 'main' with a FIXME comment, so we have a record of the bug in a regression test.

This revision is now accepted and ready to land.Dec 21 2021, 8:28 AM
rickyz updated this revision to Diff 404335.Jan 29 2022, 9:14 PM
rickyz marked an inline comment as done.

Rebasing on top of D118554.

This revision was landed with ongoing or failed builds.Jan 30 2022, 6:59 AM
This revision was automatically updated to reflect the committed changes.