1 | //===- llvm/unittest/CodeGen/SelectionDAGAddressAnalysisTest.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 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" |
10 | #include "llvm/Analysis/MemoryLocation.h" |
11 | #include "llvm/Analysis/OptimizationRemarkEmitter.h" |
12 | #include "llvm/AsmParser/Parser.h" |
13 | #include "llvm/CodeGen/MachineModuleInfo.h" |
14 | #include "llvm/CodeGen/SelectionDAG.h" |
15 | #include "llvm/CodeGen/TargetLowering.h" |
16 | #include "llvm/MC/TargetRegistry.h" |
17 | #include "llvm/Support/SourceMgr.h" |
18 | #include "llvm/Support/TargetSelect.h" |
19 | #include "llvm/Target/TargetMachine.h" |
20 | #include "gtest/gtest.h" |
21 | |
22 | namespace llvm { |
23 | |
24 | class SelectionDAGAddressAnalysisTest : public testing::Test { |
25 | protected: |
26 | static void SetUpTestCase() { |
27 | InitializeAllTargets(); |
28 | InitializeAllTargetMCs(); |
29 | } |
30 | |
31 | void SetUp() override { |
32 | StringRef Assembly = "@g = global i32 0\n" |
33 | "@g_alias = alias i32, i32* @g\n" |
34 | "define i32 @f() {\n" |
35 | " %1 = load i32, i32* @g\n" |
36 | " ret i32 %1\n" |
37 | "}" ; |
38 | |
39 | Triple TargetTriple("aarch64--" ); |
40 | std::string Error; |
41 | const Target *T = TargetRegistry::lookupTarget(ArchName: "" , TheTriple&: TargetTriple, Error); |
42 | // FIXME: These tests do not depend on AArch64 specifically, but we have to |
43 | // initialize a target. A skeleton Target for unittests would allow us to |
44 | // always run these tests. |
45 | if (!T) |
46 | GTEST_SKIP(); |
47 | |
48 | TargetOptions Options; |
49 | TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( |
50 | T->createTargetMachine(TT: "AArch64" , CPU: "" , Features: "+sve" , Options, RM: std::nullopt, |
51 | CM: std::nullopt, OL: CodeGenOptLevel::Aggressive))); |
52 | if (!TM) |
53 | GTEST_SKIP(); |
54 | |
55 | SMDiagnostic SMError; |
56 | M = parseAssemblyString(AsmString: Assembly, Err&: SMError, Context); |
57 | if (!M) |
58 | report_fatal_error(reason: SMError.getMessage()); |
59 | M->setDataLayout(TM->createDataLayout()); |
60 | |
61 | F = M->getFunction(Name: "f" ); |
62 | if (!F) |
63 | report_fatal_error(reason: "F?" ); |
64 | G = M->getGlobalVariable(Name: "g" ); |
65 | if (!G) |
66 | report_fatal_error(reason: "G?" ); |
67 | AliasedG = M->getNamedAlias(Name: "g_alias" ); |
68 | if (!AliasedG) |
69 | report_fatal_error(reason: "AliasedG?" ); |
70 | |
71 | MachineModuleInfo MMI(TM.get()); |
72 | |
73 | MF = std::make_unique<MachineFunction>(args&: *F, args&: *TM, args: *TM->getSubtargetImpl(*F), |
74 | args: 0, args&: MMI); |
75 | |
76 | DAG = std::make_unique<SelectionDAG>(args&: *TM, args: CodeGenOptLevel::None); |
77 | if (!DAG) |
78 | report_fatal_error(reason: "DAG?" ); |
79 | OptimizationRemarkEmitter ORE(F); |
80 | DAG->init(NewMF&: *MF, NewORE&: ORE, PassPtr: nullptr, LibraryInfo: nullptr, UA: nullptr, PSIin: nullptr, BFIin: nullptr, FnVarLocs: nullptr); |
81 | } |
82 | |
83 | TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { |
84 | return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); |
85 | } |
86 | |
87 | EVT getTypeToTransformTo(EVT VT) { |
88 | return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); |
89 | } |
90 | |
91 | LLVMContext Context; |
92 | std::unique_ptr<LLVMTargetMachine> TM; |
93 | std::unique_ptr<Module> M; |
94 | Function *F; |
95 | GlobalVariable *G; |
96 | GlobalAlias *AliasedG; |
97 | std::unique_ptr<MachineFunction> MF; |
98 | std::unique_ptr<SelectionDAG> DAG; |
99 | }; |
100 | |
101 | TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObject) { |
102 | SDLoc Loc; |
103 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
104 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4); |
105 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
106 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
107 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
108 | TypeSize Offset = TypeSize::getFixed(ExactSize: 0); |
109 | SDValue Value = DAG->getConstant(Val: 0, DL: Loc, VT: VecVT); |
110 | SDValue Index = DAG->getMemBasePlusOffset(Base: FIPtr, Offset, DL: Loc); |
111 | SDValue Store = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index, |
112 | PtrInfo: PtrInfo.getWithOffset(O: Offset)); |
113 | TypeSize NumBytes = cast<StoreSDNode>(Val&: Store)->getMemoryVT().getStoreSize(); |
114 | |
115 | bool IsAlias; |
116 | bool IsValid = BaseIndexOffset::computeAliasing( |
117 | Op0: Store.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes), Op1: Store.getNode(), |
118 | NumBytes1: LocationSize::precise(Value: NumBytes), DAG: *DAG, IsAlias); |
119 | |
120 | EXPECT_TRUE(IsValid); |
121 | EXPECT_TRUE(IsAlias); |
122 | } |
123 | |
124 | TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObjectUnknownSize) { |
125 | SDLoc Loc; |
126 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
127 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4); |
128 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
129 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
130 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
131 | TypeSize Offset = TypeSize::getFixed(ExactSize: 0); |
132 | SDValue Value = DAG->getConstant(Val: 0, DL: Loc, VT: VecVT); |
133 | SDValue Index = DAG->getMemBasePlusOffset(Base: FIPtr, Offset, DL: Loc); |
134 | SDValue Store = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index, |
135 | PtrInfo: PtrInfo.getWithOffset(O: Offset)); |
136 | |
137 | bool IsAlias; |
138 | bool IsValid = BaseIndexOffset::computeAliasing( |
139 | Op0: Store.getNode(), NumBytes0: LocationSize::beforeOrAfterPointer(), Op1: Store.getNode(), |
140 | NumBytes1: LocationSize::beforeOrAfterPointer(), DAG: *DAG, IsAlias); |
141 | |
142 | EXPECT_FALSE(IsValid); |
143 | } |
144 | |
145 | TEST_F(SelectionDAGAddressAnalysisTest, noAliasingFrameObjects) { |
146 | SDLoc Loc; |
147 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
148 | // <4 x i8> |
149 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4); |
150 | // <2 x i8> |
151 | auto SubVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2); |
152 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
153 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
154 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
155 | SDValue Value = DAG->getConstant(Val: 0, DL: Loc, VT: SubVecVT); |
156 | TypeSize Offset0 = TypeSize::getFixed(ExactSize: 0); |
157 | TypeSize Offset1 = SubVecVT.getStoreSize(); |
158 | SDValue Index0 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset0, DL: Loc); |
159 | SDValue Index1 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset1, DL: Loc); |
160 | SDValue Store0 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index0, |
161 | PtrInfo: PtrInfo.getWithOffset(O: Offset0)); |
162 | SDValue Store1 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index1, |
163 | PtrInfo: PtrInfo.getWithOffset(O: Offset1)); |
164 | TypeSize NumBytes0 = cast<StoreSDNode>(Val&: Store0)->getMemoryVT().getStoreSize(); |
165 | TypeSize NumBytes1 = cast<StoreSDNode>(Val&: Store1)->getMemoryVT().getStoreSize(); |
166 | |
167 | bool IsAlias; |
168 | bool IsValid = BaseIndexOffset::computeAliasing( |
169 | Op0: Store0.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes0), Op1: Store1.getNode(), |
170 | NumBytes1: LocationSize::precise(Value: NumBytes1), DAG: *DAG, IsAlias); |
171 | |
172 | EXPECT_TRUE(IsValid); |
173 | EXPECT_FALSE(IsAlias); |
174 | } |
175 | |
176 | TEST_F(SelectionDAGAddressAnalysisTest, unknownSizeFrameObjects) { |
177 | SDLoc Loc; |
178 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
179 | // <vscale x 4 x i8> |
180 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, IsScalable: true); |
181 | // <vscale x 2 x i8> |
182 | auto SubVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2, IsScalable: true); |
183 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
184 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
185 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
186 | SDValue Value = DAG->getConstant(Val: 0, DL: Loc, VT: SubVecVT); |
187 | TypeSize Offset1 = SubVecVT.getStoreSize(); |
188 | SDValue Index1 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset1, DL: Loc); |
189 | SDValue Store0 = |
190 | DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: FIPtr, PtrInfo); |
191 | SDValue Store1 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index1, |
192 | PtrInfo: MachinePointerInfo(PtrInfo.getAddrSpace())); |
193 | TypeSize NumBytes0 = cast<StoreSDNode>(Val&: Store0)->getMemoryVT().getStoreSize(); |
194 | TypeSize NumBytes1 = cast<StoreSDNode>(Val&: Store1)->getMemoryVT().getStoreSize(); |
195 | |
196 | bool IsAlias; |
197 | bool IsValid = BaseIndexOffset::computeAliasing( |
198 | Op0: Store0.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes0), Op1: Store1.getNode(), |
199 | NumBytes1: LocationSize::precise(Value: NumBytes1), DAG: *DAG, IsAlias); |
200 | |
201 | EXPECT_FALSE(IsValid); |
202 | } |
203 | |
204 | TEST_F(SelectionDAGAddressAnalysisTest, globalWithFrameObject) { |
205 | SDLoc Loc; |
206 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
207 | // <vscale x 4 x i8> |
208 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, IsScalable: true); |
209 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
210 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
211 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
212 | SDValue Value = DAG->getConstant(Val: 0, DL: Loc, VT: VecVT); |
213 | TypeSize Offset = TypeSize::getFixed(ExactSize: 0); |
214 | SDValue Index = DAG->getMemBasePlusOffset(Base: FIPtr, Offset, DL: Loc); |
215 | SDValue Store = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value, Ptr: Index, |
216 | PtrInfo: PtrInfo.getWithOffset(O: Offset)); |
217 | TypeSize NumBytes = cast<StoreSDNode>(Val&: Store)->getMemoryVT().getStoreSize(); |
218 | EVT GTy = DAG->getTargetLoweringInfo().getValueType(DL: DAG->getDataLayout(), |
219 | Ty: G->getType()); |
220 | SDValue GValue = DAG->getConstant(Val: 0, DL: Loc, VT: GTy); |
221 | SDValue GAddr = DAG->getGlobalAddress(GV: G, DL: Loc, VT: GTy); |
222 | SDValue GStore = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: GValue, Ptr: GAddr, |
223 | PtrInfo: MachinePointerInfo(G, 0)); |
224 | TypeSize GNumBytes = cast<StoreSDNode>(Val&: GStore)->getMemoryVT().getStoreSize(); |
225 | |
226 | bool IsAlias; |
227 | bool IsValid = BaseIndexOffset::computeAliasing( |
228 | Op0: Store.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes), Op1: GStore.getNode(), |
229 | NumBytes1: LocationSize::precise(Value: GNumBytes), DAG: *DAG, IsAlias); |
230 | |
231 | EXPECT_TRUE(IsValid); |
232 | EXPECT_FALSE(IsAlias); |
233 | } |
234 | |
235 | TEST_F(SelectionDAGAddressAnalysisTest, globalWithAliasedGlobal) { |
236 | SDLoc Loc; |
237 | |
238 | EVT GTy = DAG->getTargetLoweringInfo().getValueType(DL: DAG->getDataLayout(), |
239 | Ty: G->getType()); |
240 | SDValue GValue = DAG->getConstant(Val: 0, DL: Loc, VT: GTy); |
241 | SDValue GAddr = DAG->getGlobalAddress(GV: G, DL: Loc, VT: GTy); |
242 | SDValue GStore = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: GValue, Ptr: GAddr, |
243 | PtrInfo: MachinePointerInfo(G, 0)); |
244 | TypeSize GNumBytes = cast<StoreSDNode>(Val&: GStore)->getMemoryVT().getStoreSize(); |
245 | |
246 | SDValue AliasedGValue = DAG->getConstant(Val: 1, DL: Loc, VT: GTy); |
247 | SDValue AliasedGAddr = DAG->getGlobalAddress(GV: AliasedG, DL: Loc, VT: GTy); |
248 | SDValue AliasedGStore = |
249 | DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: AliasedGValue, Ptr: AliasedGAddr, |
250 | PtrInfo: MachinePointerInfo(AliasedG, 0)); |
251 | |
252 | bool IsAlias; |
253 | bool IsValid = BaseIndexOffset::computeAliasing( |
254 | Op0: GStore.getNode(), NumBytes0: LocationSize::precise(Value: GNumBytes), |
255 | Op1: AliasedGStore.getNode(), NumBytes1: LocationSize::precise(Value: GNumBytes), DAG: *DAG, IsAlias); |
256 | |
257 | // With some deeper analysis we could detect if G and AliasedG is aliasing or |
258 | // not. But computeAliasing is currently defensive and assumes that a |
259 | // GlobalAlias might alias with any global variable. |
260 | EXPECT_FALSE(IsValid); |
261 | } |
262 | |
263 | TEST_F(SelectionDAGAddressAnalysisTest, fixedSizeFrameObjectsWithinDiff) { |
264 | SDLoc Loc; |
265 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
266 | // <vscale x 4 x i8> |
267 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, IsScalable: true); |
268 | // <vscale x 2 x i8> |
269 | auto SubVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2, IsScalable: true); |
270 | // <2 x i8> |
271 | auto SubFixedVecVT2xi8 = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2); |
272 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
273 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
274 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
275 | SDValue Value0 = DAG->getConstant(Val: 0, DL: Loc, VT: SubFixedVecVT2xi8); |
276 | SDValue Value1 = DAG->getConstant(Val: 0, DL: Loc, VT: SubVecVT); |
277 | TypeSize Offset0 = TypeSize::getFixed(ExactSize: 0); |
278 | TypeSize Offset1 = SubFixedVecVT2xi8.getStoreSize(); |
279 | SDValue Index0 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset0, DL: Loc); |
280 | SDValue Index1 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset1, DL: Loc); |
281 | SDValue Store0 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value0, Ptr: Index0, |
282 | PtrInfo: PtrInfo.getWithOffset(O: Offset0)); |
283 | SDValue Store1 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value1, Ptr: Index1, |
284 | PtrInfo: PtrInfo.getWithOffset(O: Offset1)); |
285 | TypeSize NumBytes0 = cast<StoreSDNode>(Val&: Store0)->getMemoryVT().getStoreSize(); |
286 | TypeSize NumBytes1 = cast<StoreSDNode>(Val&: Store1)->getMemoryVT().getStoreSize(); |
287 | |
288 | bool IsAlias; |
289 | bool IsValid = BaseIndexOffset::computeAliasing( |
290 | Op0: Store0.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes0), Op1: Store1.getNode(), |
291 | NumBytes1: LocationSize::precise(Value: NumBytes1), DAG: *DAG, IsAlias); |
292 | EXPECT_TRUE(IsValid); |
293 | EXPECT_FALSE(IsAlias); |
294 | |
295 | IsValid = BaseIndexOffset::computeAliasing( |
296 | Op0: Store1.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes1), Op1: Store0.getNode(), |
297 | NumBytes1: LocationSize::precise(Value: NumBytes0), DAG: *DAG, IsAlias); |
298 | EXPECT_TRUE(IsValid); |
299 | EXPECT_FALSE(IsAlias); |
300 | } |
301 | |
302 | TEST_F(SelectionDAGAddressAnalysisTest, fixedSizeFrameObjectsOutOfDiff) { |
303 | SDLoc Loc; |
304 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
305 | // <vscale x 4 x i8> |
306 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, IsScalable: true); |
307 | // <vscale x 2 x i8> |
308 | auto SubVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2, IsScalable: true); |
309 | // <2 x i8> |
310 | auto SubFixedVecVT2xi8 = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2); |
311 | // <4 x i8> |
312 | auto SubFixedVecVT4xi8 = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4); |
313 | SDValue FIPtr = DAG->CreateStackTemporary(VT: VecVT); |
314 | int FI = cast<FrameIndexSDNode>(Val: FIPtr.getNode())->getIndex(); |
315 | MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF&: *MF, FI); |
316 | SDValue Value0 = DAG->getConstant(Val: 0, DL: Loc, VT: SubFixedVecVT4xi8); |
317 | SDValue Value1 = DAG->getConstant(Val: 0, DL: Loc, VT: SubVecVT); |
318 | TypeSize Offset0 = TypeSize::getFixed(ExactSize: 0); |
319 | TypeSize Offset1 = SubFixedVecVT2xi8.getStoreSize(); |
320 | SDValue Index0 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset0, DL: Loc); |
321 | SDValue Index1 = DAG->getMemBasePlusOffset(Base: FIPtr, Offset: Offset1, DL: Loc); |
322 | SDValue Store0 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value0, Ptr: Index0, |
323 | PtrInfo: PtrInfo.getWithOffset(O: Offset0)); |
324 | SDValue Store1 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value1, Ptr: Index1, |
325 | PtrInfo: PtrInfo.getWithOffset(O: Offset1)); |
326 | TypeSize NumBytes0 = cast<StoreSDNode>(Val&: Store0)->getMemoryVT().getStoreSize(); |
327 | TypeSize NumBytes1 = cast<StoreSDNode>(Val&: Store1)->getMemoryVT().getStoreSize(); |
328 | |
329 | bool IsAlias; |
330 | bool IsValid = BaseIndexOffset::computeAliasing( |
331 | Op0: Store0.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes0), Op1: Store1.getNode(), |
332 | NumBytes1: LocationSize::precise(Value: NumBytes1), DAG: *DAG, IsAlias); |
333 | EXPECT_TRUE(IsValid); |
334 | EXPECT_TRUE(IsAlias); |
335 | } |
336 | |
337 | TEST_F(SelectionDAGAddressAnalysisTest, twoFixedStackObjects) { |
338 | SDLoc Loc; |
339 | auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8); |
340 | // <vscale x 2 x i8> |
341 | auto VecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2, IsScalable: true); |
342 | // <2 x i8> |
343 | auto FixedVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 2); |
344 | SDValue FIPtr0 = DAG->CreateStackTemporary(VT: FixedVecVT); |
345 | SDValue FIPtr1 = DAG->CreateStackTemporary(VT: VecVT); |
346 | int FI0 = cast<FrameIndexSDNode>(Val: FIPtr0.getNode())->getIndex(); |
347 | int FI1 = cast<FrameIndexSDNode>(Val: FIPtr1.getNode())->getIndex(); |
348 | MachinePointerInfo PtrInfo0 = MachinePointerInfo::getFixedStack(MF&: *MF, FI: FI0); |
349 | MachinePointerInfo PtrInfo1 = MachinePointerInfo::getFixedStack(MF&: *MF, FI: FI1); |
350 | SDValue Value0 = DAG->getConstant(Val: 0, DL: Loc, VT: FixedVecVT); |
351 | SDValue Value1 = DAG->getConstant(Val: 0, DL: Loc, VT: VecVT); |
352 | TypeSize Offset0 = TypeSize::getFixed(ExactSize: 0); |
353 | SDValue Index0 = DAG->getMemBasePlusOffset(Base: FIPtr0, Offset: Offset0, DL: Loc); |
354 | SDValue Index1 = DAG->getMemBasePlusOffset(Base: FIPtr1, Offset: Offset0, DL: Loc); |
355 | SDValue Store0 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value0, Ptr: Index0, |
356 | PtrInfo: PtrInfo0.getWithOffset(O: Offset0)); |
357 | SDValue Store1 = DAG->getStore(Chain: DAG->getEntryNode(), dl: Loc, Val: Value1, Ptr: Index1, |
358 | PtrInfo: PtrInfo1.getWithOffset(O: Offset0)); |
359 | TypeSize NumBytes0 = cast<StoreSDNode>(Val&: Store0)->getMemoryVT().getStoreSize(); |
360 | TypeSize NumBytes1 = cast<StoreSDNode>(Val&: Store1)->getMemoryVT().getStoreSize(); |
361 | |
362 | bool IsAlias; |
363 | bool IsValid = BaseIndexOffset::computeAliasing( |
364 | Op0: Store0.getNode(), NumBytes0: LocationSize::precise(Value: NumBytes0), Op1: Store1.getNode(), |
365 | NumBytes1: LocationSize::precise(Value: NumBytes1), DAG: *DAG, IsAlias); |
366 | EXPECT_TRUE(IsValid); |
367 | EXPECT_FALSE(IsAlias); |
368 | } |
369 | |
370 | } // end namespace llvm |
371 | |