+AliasAnalysis::Location
+BasicAliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
+ ModRefResult &Mask) {
+ Location Loc = AliasAnalysis::getArgLocation(CS, ArgIdx, Mask);
+ const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
+ if (II != nullptr)
+ switch (II->getIntrinsicID()) {
+ default: break;
+ case Intrinsic::memset:
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove: {
+ assert((ArgIdx == 0 || ArgIdx == 1) &&
+ "Invalid argument index for memory intrinsic");
+ if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
+ Loc.Size = LenCI->getZExtValue();
+ assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
+ "Memory intrinsic location pointer not argument?");
+ Mask = ArgIdx ? Ref : Mod;
+ break;
+ }
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::invariant_start: {
+ assert(ArgIdx == 1 && "Invalid argument index");
+ assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
+ "Intrinsic location pointer not argument?");
+ Loc.Size = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
+ break;
+ }
+ case Intrinsic::invariant_end: {
+ assert(ArgIdx == 2 && "Invalid argument index");
+ assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
+ "Intrinsic location pointer not argument?");
+ Loc.Size = cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
+ break;
+ }
+ case Intrinsic::arm_neon_vld1: {
+ assert(ArgIdx == 0 && "Invalid argument index");
+ assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
+ "Intrinsic location pointer not argument?");
+ // LLVM's vld1 and vst1 intrinsics currently only support a single
+ // vector register.
+ if (DL)
+ Loc.Size = DL->getTypeStoreSize(II->getType());
+ break;
+ }
+ case Intrinsic::arm_neon_vst1: {
+ assert(ArgIdx == 0 && "Invalid argument index");
+ assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
+ "Intrinsic location pointer not argument?");
+ if (DL)
+ Loc.Size = DL->getTypeStoreSize(II->getArgOperand(1)->getType());
+ break;
+ }
+ }
+
+ // We can bound the aliasing properties of memset_pattern16 just as we can
+ // for memcpy/memset. This is particularly important because the
+ // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
+ // whenever possible.
+ else if (CS.getCalledFunction() &&
+ isMemsetPattern16(CS.getCalledFunction(), TLI)) {
+ assert((ArgIdx == 0 || ArgIdx == 1) &&
+ "Invalid argument index for memset_pattern16");
+ if (ArgIdx == 1)
+ Loc.Size = 16;
+ else if (const ConstantInt *LenCI =
+ dyn_cast<ConstantInt>(CS.getArgument(2)))
+ Loc.Size = LenCI->getZExtValue();
+ assert(Loc.Ptr == CS.getArgument(ArgIdx) &&
+ "memset_pattern16 location pointer not argument?");
+ Mask = ArgIdx ? Ref : Mod;
+ }
+ // FIXME: Handle memset_pattern4 and memset_pattern8 also.
+
+ return Loc;
+}
+
+static bool isAssumeIntrinsic(ImmutableCallSite CS) {
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
+ if (II && II->getIntrinsicID() == Intrinsic::assume)
+ return true;
+
+ return false;
+}
+