[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / CodeGen / GlobalISel / GISelAliasTest.cpp
blobcd98a05dcc2baede1584cde02efea288f82c13b5
1 //===- GISelAliasTest.cpp--------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "GISelMITest.h"
10 #include "llvm/CodeGen/GlobalISel/LoadStoreOpt.h"
11 #include "llvm/CodeGen/MachineFrameInfo.h"
12 #include "llvm/CodeGen/MachineMemOperand.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Metadata.h"
15 #include "llvm/Support/AtomicOrdering.h"
16 #include "gtest/gtest.h"
18 namespace {
20 // Test simple aliasing.
21 TEST_F(AArch64GISelMITest, SimpleAlias) {
22 setUp();
23 if (!TM)
24 return;
26 LLT S64 = LLT::scalar(64);
27 LLT P0 = LLT::pointer(0, 64);
29 auto Base = B.buildIntToPtr(P0, Copies[0]);
30 auto Base2 = B.buildIntToPtr(P0, Copies[1]);
31 // These two addresses are identical.
32 auto Addr = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
33 auto Addr2 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
35 MachinePointerInfo PtrInfo;
36 auto *LoadMMO = MF->getMachineMemOperand(
37 PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
38 auto Ld1 = B.buildLoad(S64, Addr, *LoadMMO);
39 auto Ld2 = B.buildLoad(S64, Addr2, *LoadMMO);
41 // We expect the same address to return alias.
42 EXPECT_TRUE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
44 // Expect both being volatile to say alias, since we can't reorder them.
45 auto *LoadVolMMO = MF->getMachineMemOperand(
46 LoadMMO,
47 MachineMemOperand::Flags::MOLoad | MachineMemOperand::Flags::MOVolatile);
48 // Pick a different address so we don't trivially match the alias case above.
49 auto VolLd1 = B.buildLoad(S64, Addr, *LoadVolMMO);
50 auto VolLd2 = B.buildLoad(S64, Base2, *LoadVolMMO);
51 EXPECT_TRUE(GISelAddressing::instMayAlias(*VolLd1, *VolLd2, *MRI, nullptr));
53 // Same for atomics.
54 auto *LoadAtomicMMO = MF->getMachineMemOperand(
55 PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align(8), AAMDNodes(),
56 nullptr, SyncScope::System, AtomicOrdering::Acquire);
57 auto AtomicLd1 = B.buildLoad(S64, Addr, *LoadAtomicMMO);
58 auto AtomicLd2 = B.buildLoad(S64, Base2, *LoadAtomicMMO);
59 EXPECT_TRUE(
60 GISelAddressing::instMayAlias(*AtomicLd1, *AtomicLd2, *MRI, nullptr));
62 // Invariant memory with stores.
63 auto *LoadInvariantMMO = MF->getMachineMemOperand(
64 LoadMMO,
65 MachineMemOperand::Flags::MOLoad | MachineMemOperand::Flags::MOInvariant);
66 auto InvariantLd = B.buildLoad(S64, Addr, *LoadInvariantMMO);
67 auto Store = B.buildStore(B.buildConstant(S64, 0), Base2, PtrInfo, Align());
68 EXPECT_FALSE(
69 GISelAddressing::instMayAlias(*InvariantLd, *Store, *MRI, nullptr));
72 // Test aliasing checks for same base + different offsets.
73 TEST_F(AArch64GISelMITest, OffsetAliasing) {
74 setUp();
75 if (!TM)
76 return;
78 LLT S64 = LLT::scalar(64);
79 LLT P0 = LLT::pointer(0, 64);
81 auto Base = B.buildIntToPtr(P0, Copies[0]);
82 auto Addr = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 8));
83 auto Addr2 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 16));
85 MachinePointerInfo PtrInfo;
86 auto *LoadMMO = MF->getMachineMemOperand(
87 PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
88 auto Ld1 = B.buildLoad(S64, Addr, *LoadMMO);
89 auto Ld2 = B.buildLoad(S64, Addr2, *LoadMMO);
91 // The offset between the two addresses is >= than the size of access.
92 // Can't alias.
93 EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
94 EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld2, *Ld1, *MRI, nullptr));
96 auto Addr3 = B.buildPtrAdd(P0, Base, B.buildConstant(S64, 4));
97 auto Ld3 = B.buildLoad(S64, Addr3, *LoadMMO);
98 // Offset of 4 is < the size of access, 8 bytes.
99 EXPECT_TRUE(GISelAddressing::instMayAlias(*Ld1, *Ld3, *MRI, nullptr));
102 // Test aliasing checks for frame indexes.
103 TEST_F(AArch64GISelMITest, FrameIndexAliasing) {
104 setUp();
105 if (!TM)
106 return;
108 LLT S64 = LLT::scalar(64);
109 LLT P0 = LLT::pointer(0, 64);
111 auto &MFI = MF->getFrameInfo();
112 auto FixedFI1 = MFI.CreateFixedObject(8, 0, true);
113 auto FixedFI2 = MFI.CreateFixedObject(8, 8, true);
115 auto FI1 = MFI.CreateStackObject(8, Align(8), false);
116 auto GFI1 = B.buildFrameIndex(P0, FI1);
117 // This G_FRAME_INDEX is separate but refers to the same index.
118 auto GFI2 = B.buildFrameIndex(P0, FI1);
120 MachinePointerInfo PtrInfo;
121 auto *LoadMMO = MF->getMachineMemOperand(
122 PtrInfo, MachineMemOperand::Flags::MOLoad, S64, Align());
123 auto Ld1 = B.buildLoad(S64, GFI1, *LoadMMO);
124 auto Ld2 = B.buildLoad(S64, GFI2, *LoadMMO);
126 // The offset between the two addresses is >= than the size of access.
127 // Can't alias.
128 EXPECT_FALSE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));
131 auto GFixedFI1 = B.buildFrameIndex(P0, FixedFI1);
132 auto GFixedFI2 = B.buildFrameIndex(P0, FixedFI2);
133 auto FixedFILd1 = B.buildLoad(S64, GFixedFI1, *LoadMMO);
134 auto FixedFILd2 = B.buildLoad(S64, GFixedFI2, *LoadMMO);
135 // If we have two different FrameIndex bases, but at least one is not a fixed
136 // object, then we can say they don't alias. If both were fixed, then we could
137 // have multiple frameindex slots being accessed at once since their relative
138 // positions are known. However, if one is not fixed, then they can't alias
139 // because non-fixed FIs are only given offsets during PEI.
140 EXPECT_FALSE(GISelAddressing::instMayAlias(*FixedFILd1, *Ld1, *MRI, nullptr));
141 EXPECT_TRUE(
142 GISelAddressing::instMayAlias(*FixedFILd1, *FixedFILd2, *MRI, nullptr));
145 } // namespace