This is an archive of the discontinued LLVM Phabricator instance.

[SelectionDAG] Assume that a GlobalAlias may alias other global values
ClosedPublic

Authored by bjope on Sep 20 2021, 3:59 AM.

Details

Summary

This fixes a bug detected in DAGCombiner when using global alias
variables. Here is an example:

@foo = global i16 0, align 1
@aliasFoo = alias i16, i16 * @foo
define i16 @bar() {
  ...
  store i16 7, i16 * @foo, align 1
  store i16 8, i16 * @aliasFoo, align 1
  ...
}

BaseIndexOffset::computeAliasing would incorrectly derive NoAlias
for the two accesses in the example above, resulting in DAGCombiner
miscompiles.

This patch fixes the problem by a defensive approach letting
BaseIndexOffset::computeAliasing return false, i.e. that the aliasing
couldn't be determined, when comparing two global values and at least
one is a GlobalAlias. In the future we might improve this with a
deeper analysis to look at the aliasee for the GlobalAlias etc. But
that is a bit more complicated considering that we could have
'local_unnamed_addr' and situations with several 'alias' variables.

Fixes PR51878.

Diff Detail

Event Timeline

bjope created this revision.Sep 20 2021, 3:59 AM
bjope requested review of this revision.Sep 20 2021, 3:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 20 2021, 3:59 AM
niravd added inline comments.Sep 20 2021, 5:59 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
155

It looks like we can walk the GlobalAlias to the referenced object. If so, we should fully walk to a non-alias global instead.

168

We should handle this case earlier so we can correct determine that identical global aliases do in fact alias.

bjope added inline comments.Sep 20 2021, 6:19 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
155

As I wrote in the desciption "In the future we might improve this with a deeper analysis to look at the aliasee for the GlobalAlias etc. But that is a bit more complicated considering that we could have 'local_unnamed_addr' and situations with several 'alias' variables.".

I'd actually prefer doing a bugfix that I'm confortable with. And I didn't quite understand the part about "Aliases that are not unnamed_addr are guaranteed to have the same address as the aliasee expression. unnamed_addr ones are only guaranteed to point to the same content." from https://llvm.org/docs/LangRef.html#aliases .

But if my approach was too naive and defensive, then I wonder why we have references to GlobalAlias:es in the IR in the first place. Couldn't we just reference the aliasee instead (leaving the GlobalAlias declaration as an unused declaration)?

168

Well, this if-statement derives IsAlias=false. So I'm just as confused about this check as your suggestion here. I needed to pull this check out from the orignal if-statment just to make it possible to add the check for global aliases before this. Otherwise it would derive that there is no alias between global aliases.

On the other hand, if this check of indices is considered as a bug in itself, to be removed, then my new check for global aliases isn't really needed either.

Removing this if-statement makes about 10 lit-tests to fail. Probably just due to getting slightly different codegen. Haven't really been able to prove that something is wrong with those tests.
Although, when adding a unittest that calls BaseIndexOffset::computeAliasing with the Op0 and Op1 being identical, but with NumBytes0 or NumBytes1 being unset (avoiding to enter the if at line 99) then computeAliasing would answer that there is no aliasing. That really seems wrong (but maybe that never happens in reality).

bjope added inline comments.
llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
156

Maybe it is safer to look for GlobalIndirectSymbol here instead of GlobalAlias (as that would include any other indirect reference)?

168

I think that it maybe would be safer (and more correct) to check if we access two different GlobalValue here, and then derive NoAlias. Wouldn't it be weird to access one global using the address of another GlobalValue (the actual layout in memory between globals isn't given, or is it)?

(Although my intention with this patch has been to avoid the miscompiles for GlobalAlias:es, and I had planned to leave this mess with deriving NoAlias based on having identival Index in the BaseOffsetIndex for the future.)

bjope added inline comments.Sep 22 2021, 7:53 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
168

I made a follow up for this in D110256.

Can you add a codegen test for PR51878? The example listed in your message should do.

Once I think with the follow up, this should be good to go.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
155

I don't remember why this clause was neces

bjope updated this revision to Diff 374263.Sep 22 2021, 9:34 AM

Adding a codegen reproducer.

bjope added a comment.Sep 28 2021, 3:50 AM

Can you add a codegen test for PR51878? The example listed in your message should do.

Once I think with the follow up, this should be good to go.

D110256 has not been accepted yet, but is it OK to land this now (to be able to close PR51878)?

D110256 has not been accepted yet, but is it OK to land this now (to be able to close PR51878)?

I was just waiting for you to fix the unit tests.

bjope updated this revision to Diff 375581.Sep 28 2021, 7:50 AM

Ran clang-format on unittest updates.

This revision was not accepted when it landed; it landed in state Needs Review.Oct 5 2021, 3:17 AM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.