#include "GISelMITest.h"
#include "llvm/CodeGen/GlobalISel/LoadStoreOpt.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/AtomicOrdering.h"
#include "gtest/gtest.h"
namespace {
TEST_F(AArch64GISelMITest, SimpleAlias) {
setUp();
if (!TM)
return;
LLT S64 = LLT::scalar(64);
LLT P0 = LLT::pointer(0, 64);
auto Base = B.buildIntToPtr(P0, Copies[0]);
auto Base2 = B.buildIntToPtr(P0, Copies[1]);
auto Addr = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
auto Addr2 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
MachinePointerInfo PtrInfo;
auto *LoadMMO = MF->getMachineMemOperand(
PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
auto Ld1 = B.buildLoad(S64, Addr, *LoadMMO);
auto Ld2 = B.buildLoad(S64, Addr2, *LoadMMO);
EXPECT_TRUE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
auto *LoadVolMMO = MF->getMachineMemOperand(
LoadMMO,
MachineMemOperand::Flags::MOLoad | MachineMemOperand::Flags::MOVolatile);
auto VolLd1 = B.buildLoad(S64, Addr, *LoadVolMMO);
auto VolLd2 = B.buildLoad(S64, Base2, *LoadVolMMO);
EXPECT_TRUE(GISelAddressing::instMayAlias(*VolLd1, *VolLd2, *MRI, nullptr));
auto *LoadAtomicMMO = MF->getMachineMemOperand(
PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align(8), AAMDNodes(),
nullptr, SyncScope::System, AtomicOrdering::Acquire);
auto AtomicLd1 = B.buildLoad(S64, Addr, *LoadAtomicMMO);
auto AtomicLd2 = B.buildLoad(S64, Base2, *LoadAtomicMMO);
EXPECT_TRUE(
GISelAddressing::instMayAlias(*AtomicLd1, *AtomicLd2, *MRI, nullptr));
auto *LoadInvariantMMO = MF->getMachineMemOperand(
LoadMMO,
MachineMemOperand::Flags::MOLoad | MachineMemOperand::Flags::MOInvariant);
auto InvariantLd = B.buildLoad(S64, Addr, *LoadInvariantMMO);
auto Store = B.buildStore(B.buildConstant(S64, 0), Base2, PtrInfo, Align());
EXPECT_FALSE(
GISelAddressing::instMayAlias(*InvariantLd, *Store, *MRI, nullptr));
}
TEST_F(AArch64GISelMITest, OffsetAliasing) {
setUp();
if (!TM)
return;
LLT S64 = LLT::scalar(64);
LLT P0 = LLT::pointer(0, 64);
auto Base = B.buildIntToPtr(P0, Copies[0]);
auto Addr = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
auto Addr2 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 16));
MachinePointerInfo PtrInfo;
auto *LoadMMO = MF->getMachineMemOperand(
PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
auto Ld1 = B.buildLoad(S64, Addr, *LoadMMO);
auto Ld2 = B.buildLoad(S64, Addr2, *LoadMMO);
EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld2, *Ld1, *MRI, nullptr));
auto Addr3 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 4));
auto Ld3 = B.buildLoad(S64, Addr3, *LoadMMO);
EXPECT_TRUE(GISelAddressing::instMayAlias(*Ld1, *Ld3, *MRI, nullptr));
}
TEST_F(AArch64GISelMITest, FrameIndexAliasing) {
setUp();
if (!TM)
return;
LLT S64 = LLT::scalar(64);
LLT P0 = LLT::pointer(0, 64);
auto &MFI = MF->getFrameInfo();
auto FixedFI1 = MFI.CreateFixedObject(8, 0, true);
auto FixedFI2 = MFI.CreateFixedObject(8, 8, true);
auto FI1 = MFI.CreateStackObject(8, Align(8), false);
auto GFI1 = B.buildFrameIndex(P0, FI1);
auto GFI2 = B.buildFrameIndex(P0, FI1);
MachinePointerInfo PtrInfo;
auto *LoadMMO = MF->getMachineMemOperand(
PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
auto Ld1 = B.buildLoad(S64, GFI1, *LoadMMO);
auto Ld2 = B.buildLoad(S64, GFI2, *LoadMMO);
EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
auto GFixedFI1 = B.buildFrameIndex(P0, FixedFI1);
auto GFixedFI2 = B.buildFrameIndex(P0, FixedFI2);
auto FixedFILd1 = B.buildLoad(S64, GFixedFI1, *LoadMMO);
auto FixedFILd2 = B.buildLoad(S64, GFixedFI2, *LoadMMO);
EXPECT_FALSE(GISelAddressing::instMayAlias(*FixedFILd1, *Ld1, *MRI, nullptr));
EXPECT_TRUE(
GISelAddressing::instMayAlias(*FixedFILd1, *FixedFILd2, *MRI, nullptr));
}
}