diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp @@ -150,24 +150,20 @@ IsAlias = false; return true; } - // We cannot safely determine whether the pointers alias if we compare two - // global values and at least one is a GlobalAlias. - if (IsGV0 && IsGV1 && - (isa( - cast(BasePtr0.getBase())->getGlobal()) || - isa( - cast(BasePtr1.getBase())->getGlobal()))) - return false; - // If checkable indices we can check they do not alias. - // FIXME: Please describe this a bit better. Looks weird to say that there - // is no alias if the indices are the same. Is this code assuming that - // someone has checked that the base isn't the same as a precondition? And - // what about offsets? And what about NumBytes0 and NumBytest1 (can we - // really derive NoAlias here if we do not even know how many bytes that are - // dereferenced)? - if (BasePtr0.getIndex() == BasePtr1.getIndex()) { - IsAlias = false; - return true; + if (IsGV0 && IsGV1) { + auto *GV0 = cast(BasePtr0.getBase())->getGlobal(); + auto *GV1 = cast(BasePtr1.getBase())->getGlobal(); + // It doesn't make sense to access one global value using another globals + // values address, so we can assume that there is no aliasing in case of + // two different globals (unless we have symbols that may indirectly point + // to each other). + // FIXME: This is perhaps a bit too defensive. We could try to follow the + // chain with aliasee information for GlobalAlias variables to find out if + // we indirect symbols may alias or not. + if (GV0 != GV1 && !isa(GV0) && !isa(GV1)) { + IsAlias = false; + return true; + } } } return false; // Cannot determine whether the pointers alias. diff --git a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp --- a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp @@ -121,6 +121,31 @@ EXPECT_TRUE(IsAlias); } +TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObjectUnknownSize) { + SDLoc Loc; + auto Int8VT = EVT::getIntegerVT(Context, 8); + auto VecVT = EVT::getVectorVT(Context, Int8VT, 4); + SDValue FIPtr = DAG->CreateStackTemporary(VecVT); + int FI = cast(FIPtr.getNode())->getIndex(); + MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI); + TypeSize Offset = TypeSize::Fixed(0); + SDValue Value = DAG->getConstant(0, Loc, VecVT); + SDValue Index = DAG->getMemBasePlusOffset(FIPtr, Offset, Loc); + SDValue Store = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index, + PtrInfo.getWithOffset(Offset)); + + // Maybe unlikely that BaseIndexOffset::computeAliasing is used with the + // optional NumBytes being unset like in this test, but it would be confusing + // if that function determined IsAlias=false here. + Optional NumBytes; + + bool IsAlias; + bool IsValid = BaseIndexOffset::computeAliasing( + Store.getNode(), NumBytes, Store.getNode(), NumBytes, *DAG, IsAlias); + + EXPECT_FALSE(IsValid); +} + TEST_F(SelectionDAGAddressAnalysisTest, noAliasingFrameObjects) { SDLoc Loc; auto Int8VT = EVT::getIntegerVT(Context, 8);