1284184Sdim//===- MemoryLocation.cpp - Memory location descriptions -------------------==// 2284184Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6284184Sdim// 7284184Sdim//===----------------------------------------------------------------------===// 8284184Sdim 9284184Sdim#include "llvm/Analysis/MemoryLocation.h" 10284734Sdim#include "llvm/Analysis/TargetLibraryInfo.h" 11284184Sdim#include "llvm/IR/BasicBlock.h" 12284184Sdim#include "llvm/IR/DataLayout.h" 13284184Sdim#include "llvm/IR/Instructions.h" 14284184Sdim#include "llvm/IR/IntrinsicInst.h" 15360784Sdim#include "llvm/IR/IntrinsicsARM.h" 16284184Sdim#include "llvm/IR/LLVMContext.h" 17284184Sdim#include "llvm/IR/Module.h" 18284184Sdim#include "llvm/IR/Type.h" 19284184Sdimusing namespace llvm; 20284184Sdim 21344779Sdimvoid LocationSize::print(raw_ostream &OS) const { 22344779Sdim OS << "LocationSize::"; 23344779Sdim if (*this == unknown()) 24344779Sdim OS << "unknown"; 25344779Sdim else if (*this == mapEmpty()) 26344779Sdim OS << "mapEmpty"; 27344779Sdim else if (*this == mapTombstone()) 28344779Sdim OS << "mapTombstone"; 29344779Sdim else if (isPrecise()) 30344779Sdim OS << "precise(" << getValue() << ')'; 31344779Sdim else 32344779Sdim OS << "upperBound(" << getValue() << ')'; 33344779Sdim} 34344779Sdim 35284184SdimMemoryLocation MemoryLocation::get(const LoadInst *LI) { 36284184Sdim AAMDNodes AATags; 37284184Sdim LI->getAAMetadata(AATags); 38284184Sdim const auto &DL = LI->getModule()->getDataLayout(); 39284184Sdim 40344779Sdim return MemoryLocation( 41344779Sdim LI->getPointerOperand(), 42344779Sdim LocationSize::precise(DL.getTypeStoreSize(LI->getType())), AATags); 43284184Sdim} 44284184Sdim 45284184SdimMemoryLocation MemoryLocation::get(const StoreInst *SI) { 46284184Sdim AAMDNodes AATags; 47284184Sdim SI->getAAMetadata(AATags); 48284184Sdim const auto &DL = SI->getModule()->getDataLayout(); 49284184Sdim 50284184Sdim return MemoryLocation(SI->getPointerOperand(), 51344779Sdim LocationSize::precise(DL.getTypeStoreSize( 52344779Sdim SI->getValueOperand()->getType())), 53284184Sdim AATags); 54284184Sdim} 55284184Sdim 56284184SdimMemoryLocation MemoryLocation::get(const VAArgInst *VI) { 57284184Sdim AAMDNodes AATags; 58284184Sdim VI->getAAMetadata(AATags); 59284184Sdim 60344779Sdim return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(), 61344779Sdim AATags); 62284184Sdim} 63284184Sdim 64284184SdimMemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { 65284184Sdim AAMDNodes AATags; 66284184Sdim CXI->getAAMetadata(AATags); 67284184Sdim const auto &DL = CXI->getModule()->getDataLayout(); 68284184Sdim 69344779Sdim return MemoryLocation(CXI->getPointerOperand(), 70344779Sdim LocationSize::precise(DL.getTypeStoreSize( 71344779Sdim CXI->getCompareOperand()->getType())), 72344779Sdim AATags); 73284184Sdim} 74284184Sdim 75284184SdimMemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { 76284184Sdim AAMDNodes AATags; 77284184Sdim RMWI->getAAMetadata(AATags); 78284184Sdim const auto &DL = RMWI->getModule()->getDataLayout(); 79284184Sdim 80284184Sdim return MemoryLocation(RMWI->getPointerOperand(), 81344779Sdim LocationSize::precise(DL.getTypeStoreSize( 82344779Sdim RMWI->getValOperand()->getType())), 83284184Sdim AATags); 84284184Sdim} 85284184Sdim 86284184SdimMemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { 87341825Sdim return getForSource(cast<AnyMemTransferInst>(MTI)); 88341825Sdim} 89341825Sdim 90341825SdimMemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) { 91341825Sdim return getForSource(cast<AnyMemTransferInst>(MTI)); 92341825Sdim} 93341825Sdim 94341825SdimMemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) { 95344779Sdim auto Size = LocationSize::unknown(); 96284184Sdim if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength())) 97344779Sdim Size = LocationSize::precise(C->getValue().getZExtValue()); 98284184Sdim 99284184Sdim // memcpy/memmove can have AA tags. For memcpy, they apply 100284184Sdim // to both the source and the destination. 101284184Sdim AAMDNodes AATags; 102284184Sdim MTI->getAAMetadata(AATags); 103284184Sdim 104284184Sdim return MemoryLocation(MTI->getRawSource(), Size, AATags); 105284184Sdim} 106284184Sdim 107341825SdimMemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) { 108341825Sdim return getForDest(cast<AnyMemIntrinsic>(MI)); 109341825Sdim} 110341825Sdim 111341825SdimMemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) { 112341825Sdim return getForDest(cast<AnyMemIntrinsic>(MI)); 113341825Sdim} 114341825Sdim 115341825SdimMemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { 116344779Sdim auto Size = LocationSize::unknown(); 117341825Sdim if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength())) 118344779Sdim Size = LocationSize::precise(C->getValue().getZExtValue()); 119284184Sdim 120284184Sdim // memcpy/memmove can have AA tags. For memcpy, they apply 121284184Sdim // to both the source and the destination. 122284184Sdim AAMDNodes AATags; 123341825Sdim MI->getAAMetadata(AATags); 124284184Sdim 125341825Sdim return MemoryLocation(MI->getRawDest(), Size, AATags); 126284184Sdim} 127284734Sdim 128344779SdimMemoryLocation MemoryLocation::getForArgument(const CallBase *Call, 129284734Sdim unsigned ArgIdx, 130344779Sdim const TargetLibraryInfo *TLI) { 131284734Sdim AAMDNodes AATags; 132344779Sdim Call->getAAMetadata(AATags); 133344779Sdim const Value *Arg = Call->getArgOperand(ArgIdx); 134284734Sdim 135284734Sdim // We may be able to produce an exact size for known intrinsics. 136344779Sdim if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) { 137284734Sdim const DataLayout &DL = II->getModule()->getDataLayout(); 138284734Sdim 139284734Sdim switch (II->getIntrinsicID()) { 140284734Sdim default: 141284734Sdim break; 142284734Sdim case Intrinsic::memset: 143284734Sdim case Intrinsic::memcpy: 144284734Sdim case Intrinsic::memmove: 145284734Sdim assert((ArgIdx == 0 || ArgIdx == 1) && 146284734Sdim "Invalid argument index for memory intrinsic"); 147284734Sdim if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) 148344779Sdim return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), 149344779Sdim AATags); 150284734Sdim break; 151284734Sdim 152284734Sdim case Intrinsic::lifetime_start: 153284734Sdim case Intrinsic::lifetime_end: 154284734Sdim case Intrinsic::invariant_start: 155284734Sdim assert(ArgIdx == 1 && "Invalid argument index"); 156284734Sdim return MemoryLocation( 157344779Sdim Arg, 158344779Sdim LocationSize::precise( 159344779Sdim cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()), 160344779Sdim AATags); 161284734Sdim 162284734Sdim case Intrinsic::invariant_end: 163344779Sdim // The first argument to an invariant.end is a "descriptor" type (e.g. a 164344779Sdim // pointer to a empty struct) which is never actually dereferenced. 165344779Sdim if (ArgIdx == 0) 166344779Sdim return MemoryLocation(Arg, LocationSize::precise(0), AATags); 167284734Sdim assert(ArgIdx == 2 && "Invalid argument index"); 168284734Sdim return MemoryLocation( 169344779Sdim Arg, 170344779Sdim LocationSize::precise( 171344779Sdim cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()), 172344779Sdim AATags); 173284734Sdim 174284734Sdim case Intrinsic::arm_neon_vld1: 175284734Sdim assert(ArgIdx == 0 && "Invalid argument index"); 176284734Sdim // LLVM's vld1 and vst1 intrinsics currently only support a single 177284734Sdim // vector register. 178344779Sdim return MemoryLocation( 179344779Sdim Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())), 180344779Sdim AATags); 181284734Sdim 182284734Sdim case Intrinsic::arm_neon_vst1: 183284734Sdim assert(ArgIdx == 0 && "Invalid argument index"); 184344779Sdim return MemoryLocation(Arg, 185344779Sdim LocationSize::precise(DL.getTypeStoreSize( 186344779Sdim II->getArgOperand(1)->getType())), 187344779Sdim AATags); 188284734Sdim } 189284734Sdim } 190284734Sdim 191284734Sdim // We can bound the aliasing properties of memset_pattern16 just as we can 192284734Sdim // for memcpy/memset. This is particularly important because the 193284734Sdim // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 194284734Sdim // whenever possible. 195321369Sdim LibFunc F; 196344779Sdim if (TLI && Call->getCalledFunction() && 197344779Sdim TLI->getLibFunc(*Call->getCalledFunction(), F) && 198344779Sdim F == LibFunc_memset_pattern16 && TLI->has(F)) { 199284734Sdim assert((ArgIdx == 0 || ArgIdx == 1) && 200284734Sdim "Invalid argument index for memset_pattern16"); 201284734Sdim if (ArgIdx == 1) 202344779Sdim return MemoryLocation(Arg, LocationSize::precise(16), AATags); 203344779Sdim if (const ConstantInt *LenCI = 204344779Sdim dyn_cast<ConstantInt>(Call->getArgOperand(2))) 205344779Sdim return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), 206344779Sdim AATags); 207284734Sdim } 208284734Sdim // FIXME: Handle memset_pattern4 and memset_pattern8 also. 209284734Sdim 210344779Sdim return MemoryLocation(Call->getArgOperand(ArgIdx), LocationSize::unknown(), 211344779Sdim AATags); 212284734Sdim} 213