brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 992866f Raw
146 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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"17 18namespace {19 20// Test simple aliasing.21TEST_F(AArch64GISelMITest, SimpleAlias) {22  setUp();23  if (!TM)24    GTEST_SKIP();25 26  LLT S64 = LLT::scalar(64);27  LLT P0 = LLT::pointer(0, 64);28 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));34 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);40 41  // We expect the same address to return alias.42  EXPECT_TRUE(GISelAddressing::instMayAlias(*Ld1, *Ld2, *MRI, nullptr));43 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));52 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));61 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));70}71 72// Test aliasing checks for same base + different offsets.73TEST_F(AArch64GISelMITest, OffsetAliasing) {74  setUp();75  if (!TM)76    GTEST_SKIP();77 78  LLT S64 = LLT::scalar(64);79  LLT P0 = LLT::pointer(0, 64);80 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));84 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);90 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));95 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));100}101 102// Test aliasing checks for frame indexes.103TEST_F(AArch64GISelMITest, FrameIndexAliasing) {104  setUp();105  if (!TM)106    GTEST_SKIP();107 108  LLT S64 = LLT::scalar(64);109  LLT P0 = LLT::pointer(0, 64);110 111  auto &MFI = MF->getFrameInfo();112  auto FixedFI1 = MFI.CreateFixedObject(8, 0, true);113  auto FixedFI2 = MFI.CreateFixedObject(8, 8, true);114 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);119 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);125 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));129 130 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 fixed136  // object, then we can say they don't alias. If both were fixed, then we could137  // have multiple frameindex slots being accessed at once since their relative138  // positions are known. However, if one is not fixed, then they can't alias139  // 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));143}144 145} // namespace146