287 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"10#include "SelectionDAGTestBase.h"11#include "llvm/Analysis/MemoryLocation.h"12 13namespace llvm {14 15class SelectionDAGAddressAnalysisTest : public SelectionDAGTestBase {};16 17TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObject) {18 SDLoc Loc;19 auto Int8VT = EVT::getIntegerVT(Context, 8);20 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4);21 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);22 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();23 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);24 TypeSize Offset = TypeSize::getFixed(0);25 SDValue Value = DAG->getConstant(0, Loc, VecVT);26 SDValue Index = DAG->getMemBasePlusOffset(FIPtr, Offset, Loc);27 SDValue Store = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index,28 PtrInfo.getWithOffset(Offset));29 TypeSize NumBytes = cast<StoreSDNode>(Store)->getMemoryVT().getStoreSize();30 31 bool IsAlias;32 bool IsValid = BaseIndexOffset::computeAliasing(33 Store.getNode(), LocationSize::precise(NumBytes), Store.getNode(),34 LocationSize::precise(NumBytes), *DAG, IsAlias);35 36 EXPECT_TRUE(IsValid);37 EXPECT_TRUE(IsAlias);38}39 40TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObjectUnknownSize) {41 SDLoc Loc;42 auto Int8VT = EVT::getIntegerVT(Context, 8);43 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4);44 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);45 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();46 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);47 TypeSize Offset = TypeSize::getFixed(0);48 SDValue Value = DAG->getConstant(0, Loc, VecVT);49 SDValue Index = DAG->getMemBasePlusOffset(FIPtr, Offset, Loc);50 SDValue Store = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index,51 PtrInfo.getWithOffset(Offset));52 53 bool IsAlias;54 bool IsValid = BaseIndexOffset::computeAliasing(55 Store.getNode(), LocationSize::beforeOrAfterPointer(), Store.getNode(),56 LocationSize::beforeOrAfterPointer(), *DAG, IsAlias);57 58 EXPECT_FALSE(IsValid);59}60 61TEST_F(SelectionDAGAddressAnalysisTest, noAliasingFrameObjects) {62 SDLoc Loc;63 auto Int8VT = EVT::getIntegerVT(Context, 8);64 // <4 x i8>65 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4);66 // <2 x i8>67 auto SubVecVT = EVT::getVectorVT(Context, Int8VT, 2);68 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);69 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();70 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);71 SDValue Value = DAG->getConstant(0, Loc, SubVecVT);72 TypeSize Offset0 = TypeSize::getFixed(0);73 TypeSize Offset1 = SubVecVT.getStoreSize();74 SDValue Index0 = DAG->getMemBasePlusOffset(FIPtr, Offset0, Loc);75 SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr, Offset1, Loc);76 SDValue Store0 = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index0,77 PtrInfo.getWithOffset(Offset0));78 SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index1,79 PtrInfo.getWithOffset(Offset1));80 TypeSize NumBytes0 = cast<StoreSDNode>(Store0)->getMemoryVT().getStoreSize();81 TypeSize NumBytes1 = cast<StoreSDNode>(Store1)->getMemoryVT().getStoreSize();82 83 bool IsAlias;84 bool IsValid = BaseIndexOffset::computeAliasing(85 Store0.getNode(), LocationSize::precise(NumBytes0), Store1.getNode(),86 LocationSize::precise(NumBytes1), *DAG, IsAlias);87 88 EXPECT_TRUE(IsValid);89 EXPECT_FALSE(IsAlias);90}91 92TEST_F(SelectionDAGAddressAnalysisTest, unknownSizeFrameObjects) {93 SDLoc Loc;94 auto Int8VT = EVT::getIntegerVT(Context, 8);95 // <vscale x 4 x i8>96 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4, true);97 // <vscale x 2 x i8>98 auto SubVecVT = EVT::getVectorVT(Context, Int8VT, 2, true);99 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);100 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();101 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);102 SDValue Value = DAG->getConstant(0, Loc, SubVecVT);103 TypeSize Offset1 = SubVecVT.getStoreSize();104 SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr, Offset1, Loc);105 SDValue Store0 =106 DAG->getStore(DAG->getEntryNode(), Loc, Value, FIPtr, PtrInfo);107 SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index1,108 MachinePointerInfo(PtrInfo.getAddrSpace()));109 TypeSize NumBytes0 = cast<StoreSDNode>(Store0)->getMemoryVT().getStoreSize();110 TypeSize NumBytes1 = cast<StoreSDNode>(Store1)->getMemoryVT().getStoreSize();111 112 bool IsAlias;113 bool IsValid = BaseIndexOffset::computeAliasing(114 Store0.getNode(), LocationSize::precise(NumBytes0), Store1.getNode(),115 LocationSize::precise(NumBytes1), *DAG, IsAlias);116 117 EXPECT_FALSE(IsValid);118}119 120TEST_F(SelectionDAGAddressAnalysisTest, globalWithFrameObject) {121 SDLoc Loc;122 auto Int8VT = EVT::getIntegerVT(Context, 8);123 // <vscale x 4 x i8>124 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4, true);125 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);126 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();127 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);128 SDValue Value = DAG->getConstant(0, Loc, VecVT);129 TypeSize Offset = TypeSize::getFixed(0);130 SDValue Index = DAG->getMemBasePlusOffset(FIPtr, Offset, Loc);131 SDValue Store = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index,132 PtrInfo.getWithOffset(Offset));133 TypeSize NumBytes = cast<StoreSDNode>(Store)->getMemoryVT().getStoreSize();134 EVT GTy = DAG->getTargetLoweringInfo().getValueType(DAG->getDataLayout(),135 G->getType());136 SDValue GValue = DAG->getConstant(0, Loc, GTy);137 SDValue GAddr = DAG->getGlobalAddress(G, Loc, GTy);138 SDValue GStore = DAG->getStore(DAG->getEntryNode(), Loc, GValue, GAddr,139 MachinePointerInfo(G, 0));140 TypeSize GNumBytes = cast<StoreSDNode>(GStore)->getMemoryVT().getStoreSize();141 142 bool IsAlias;143 bool IsValid = BaseIndexOffset::computeAliasing(144 Store.getNode(), LocationSize::precise(NumBytes), GStore.getNode(),145 LocationSize::precise(GNumBytes), *DAG, IsAlias);146 147 EXPECT_TRUE(IsValid);148 EXPECT_FALSE(IsAlias);149}150 151TEST_F(SelectionDAGAddressAnalysisTest, globalWithAliasedGlobal) {152 SDLoc Loc;153 154 EVT GTy = DAG->getTargetLoweringInfo().getValueType(DAG->getDataLayout(),155 G->getType());156 SDValue GValue = DAG->getConstant(0, Loc, GTy);157 SDValue GAddr = DAG->getGlobalAddress(G, Loc, GTy);158 SDValue GStore = DAG->getStore(DAG->getEntryNode(), Loc, GValue, GAddr,159 MachinePointerInfo(G, 0));160 TypeSize GNumBytes = cast<StoreSDNode>(GStore)->getMemoryVT().getStoreSize();161 162 SDValue AliasedGValue = DAG->getConstant(1, Loc, GTy);163 SDValue AliasedGAddr = DAG->getGlobalAddress(AliasedG, Loc, GTy);164 SDValue AliasedGStore =165 DAG->getStore(DAG->getEntryNode(), Loc, AliasedGValue, AliasedGAddr,166 MachinePointerInfo(AliasedG, 0));167 168 bool IsAlias;169 bool IsValid = BaseIndexOffset::computeAliasing(170 GStore.getNode(), LocationSize::precise(GNumBytes),171 AliasedGStore.getNode(), LocationSize::precise(GNumBytes), *DAG, IsAlias);172 173 // With some deeper analysis we could detect if G and AliasedG is aliasing or174 // not. But computeAliasing is currently defensive and assumes that a175 // GlobalAlias might alias with any global variable.176 EXPECT_FALSE(IsValid);177}178 179TEST_F(SelectionDAGAddressAnalysisTest, fixedSizeFrameObjectsWithinDiff) {180 SDLoc Loc;181 auto Int8VT = EVT::getIntegerVT(Context, 8);182 // <vscale x 4 x i8>183 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4, true);184 // <vscale x 2 x i8>185 auto SubVecVT = EVT::getVectorVT(Context, Int8VT, 2, true);186 // <2 x i8>187 auto SubFixedVecVT2xi8 = EVT::getVectorVT(Context, Int8VT, 2);188 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);189 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();190 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);191 SDValue Value0 = DAG->getConstant(0, Loc, SubFixedVecVT2xi8);192 SDValue Value1 = DAG->getConstant(0, Loc, SubVecVT);193 TypeSize Offset0 = TypeSize::getFixed(0);194 TypeSize Offset1 = SubFixedVecVT2xi8.getStoreSize();195 SDValue Index0 = DAG->getMemBasePlusOffset(FIPtr, Offset0, Loc);196 SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr, Offset1, Loc);197 SDValue Store0 = DAG->getStore(DAG->getEntryNode(), Loc, Value0, Index0,198 PtrInfo.getWithOffset(Offset0));199 SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value1, Index1,200 PtrInfo.getWithOffset(Offset1));201 TypeSize NumBytes0 = cast<StoreSDNode>(Store0)->getMemoryVT().getStoreSize();202 TypeSize NumBytes1 = cast<StoreSDNode>(Store1)->getMemoryVT().getStoreSize();203 204 bool IsAlias;205 bool IsValid = BaseIndexOffset::computeAliasing(206 Store0.getNode(), LocationSize::precise(NumBytes0), Store1.getNode(),207 LocationSize::precise(NumBytes1), *DAG, IsAlias);208 EXPECT_TRUE(IsValid);209 EXPECT_FALSE(IsAlias);210 211 IsValid = BaseIndexOffset::computeAliasing(212 Store1.getNode(), LocationSize::precise(NumBytes1), Store0.getNode(),213 LocationSize::precise(NumBytes0), *DAG, IsAlias);214 EXPECT_TRUE(IsValid);215 EXPECT_FALSE(IsAlias);216}217 218TEST_F(SelectionDAGAddressAnalysisTest, fixedSizeFrameObjectsOutOfDiff) {219 SDLoc Loc;220 auto Int8VT = EVT::getIntegerVT(Context, 8);221 // <vscale x 4 x i8>222 auto VecVT = EVT::getVectorVT(Context, Int8VT, 4, true);223 // <vscale x 2 x i8>224 auto SubVecVT = EVT::getVectorVT(Context, Int8VT, 2, true);225 // <2 x i8>226 auto SubFixedVecVT2xi8 = EVT::getVectorVT(Context, Int8VT, 2);227 // <4 x i8>228 auto SubFixedVecVT4xi8 = EVT::getVectorVT(Context, Int8VT, 4);229 SDValue FIPtr = DAG->CreateStackTemporary(VecVT);230 int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();231 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(*MF, FI);232 SDValue Value0 = DAG->getConstant(0, Loc, SubFixedVecVT4xi8);233 SDValue Value1 = DAG->getConstant(0, Loc, SubVecVT);234 TypeSize Offset0 = TypeSize::getFixed(0);235 TypeSize Offset1 = SubFixedVecVT2xi8.getStoreSize();236 SDValue Index0 = DAG->getMemBasePlusOffset(FIPtr, Offset0, Loc);237 SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr, Offset1, Loc);238 SDValue Store0 = DAG->getStore(DAG->getEntryNode(), Loc, Value0, Index0,239 PtrInfo.getWithOffset(Offset0));240 SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value1, Index1,241 PtrInfo.getWithOffset(Offset1));242 TypeSize NumBytes0 = cast<StoreSDNode>(Store0)->getMemoryVT().getStoreSize();243 TypeSize NumBytes1 = cast<StoreSDNode>(Store1)->getMemoryVT().getStoreSize();244 245 bool IsAlias;246 bool IsValid = BaseIndexOffset::computeAliasing(247 Store0.getNode(), LocationSize::precise(NumBytes0), Store1.getNode(),248 LocationSize::precise(NumBytes1), *DAG, IsAlias);249 EXPECT_TRUE(IsValid);250 EXPECT_TRUE(IsAlias);251}252 253TEST_F(SelectionDAGAddressAnalysisTest, twoFixedStackObjects) {254 SDLoc Loc;255 auto Int8VT = EVT::getIntegerVT(Context, 8);256 // <vscale x 2 x i8>257 auto VecVT = EVT::getVectorVT(Context, Int8VT, 2, true);258 // <2 x i8>259 auto FixedVecVT = EVT::getVectorVT(Context, Int8VT, 2);260 SDValue FIPtr0 = DAG->CreateStackTemporary(FixedVecVT);261 SDValue FIPtr1 = DAG->CreateStackTemporary(VecVT);262 int FI0 = cast<FrameIndexSDNode>(FIPtr0.getNode())->getIndex();263 int FI1 = cast<FrameIndexSDNode>(FIPtr1.getNode())->getIndex();264 MachinePointerInfo PtrInfo0 = MachinePointerInfo::getFixedStack(*MF, FI0);265 MachinePointerInfo PtrInfo1 = MachinePointerInfo::getFixedStack(*MF, FI1);266 SDValue Value0 = DAG->getConstant(0, Loc, FixedVecVT);267 SDValue Value1 = DAG->getConstant(0, Loc, VecVT);268 TypeSize Offset0 = TypeSize::getFixed(0);269 SDValue Index0 = DAG->getMemBasePlusOffset(FIPtr0, Offset0, Loc);270 SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr1, Offset0, Loc);271 SDValue Store0 = DAG->getStore(DAG->getEntryNode(), Loc, Value0, Index0,272 PtrInfo0.getWithOffset(Offset0));273 SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value1, Index1,274 PtrInfo1.getWithOffset(Offset0));275 TypeSize NumBytes0 = cast<StoreSDNode>(Store0)->getMemoryVT().getStoreSize();276 TypeSize NumBytes1 = cast<StoreSDNode>(Store1)->getMemoryVT().getStoreSize();277 278 bool IsAlias;279 bool IsValid = BaseIndexOffset::computeAliasing(280 Store0.getNode(), LocationSize::precise(NumBytes0), Store1.getNode(),281 LocationSize::precise(NumBytes1), *DAG, IsAlias);282 EXPECT_TRUE(IsValid);283 EXPECT_FALSE(IsAlias);284}285 286} // end namespace llvm287