/// originally inserted callsites were DCE'ed after they were cloned.
std::vector<WeakTrackingVH> OperandBundleCallSites;
+ /// Like VMap, but maps only unsimplified instructions. Values in the map
+ /// may be dangling, it is only intended to be used via isSimplified(), to
+ /// check whether the main VMap mapping involves simplification or not.
+ DenseMap<const Value *, const Value *> OrigVMap;
+
ClonedCodeInfo() = default;
+
+ bool isSimplified(const Value *From, const Value *To) const {
+ return OrigVMap.lookup(From) != To;
+ }
};
/// Return a copy of the specified basic block, but without
NewBB->getInstList().push_back(NewInst);
hasCalls |= (isa<CallInst>(II) && !isa<DbgInfoIntrinsic>(II));
- if (CodeInfo)
+ if (CodeInfo) {
+ CodeInfo->OrigVMap[&*II] = NewInst;
if (auto *CB = dyn_cast<CallBase>(&*II))
if (CB->hasOperandBundles())
CodeInfo->OperandBundleCallSites.push_back(NewInst);
+ }
if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
if (isa<ConstantInt>(AI->getArraySize()))
NewBB->getInstList().push_back(NewInst);
VMap[OldTI] = NewInst; // Add instruction map to value.
- if (CodeInfo)
+ if (CodeInfo) {
+ CodeInfo->OrigVMap[OldTI] = NewInst;
if (auto *CB = dyn_cast<CallBase>(OldTI))
if (CB->hasOperandBundles())
CodeInfo->OperandBundleCallSites.push_back(NewInst);
+ }
// Recursively clone any reachable successor blocks.
append_range(ToClone, successors(BB->getTerminator()));
/// parameters with noalias metadata specifying the new scope, and tag all
/// non-derived loads, stores and memory intrinsics with the new alias scopes.
static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
- const DataLayout &DL, AAResults *CalleeAAR) {
+ const DataLayout &DL, AAResults *CalleeAAR,
+ ClonedCodeInfo &InlinedFunctionInfo) {
if (!EnableNoAliasConversion)
return;
continue;
Instruction *NI = dyn_cast<Instruction>(VMI->second);
- if (!NI)
+ if (!NI || InlinedFunctionInfo.isSimplified(I, NI))
continue;
bool IsArgMemOnlyCall = false, IsFuncCall = false;
SAMetadataCloner.remap(FirstNewBlock, Caller->end());
// Add noalias metadata if necessary.
- AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR);
+ AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR, InlinedFunctionInfo);
// Clone return attributes on the callsite into the calls within the inlined
// function which feed into its return value.
ret <2 x i8> %ret
}
-; TODO: The load should not have !noalias.
+; The load should not have !noalias.
define void @caller1(<2 x i8>* %ptr1, <2 x i8>* %ptr2) {
; CHECK-LABEL: @caller1(
-; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !noalias !0
+; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2{{$}}
; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !0
; CHECK-NEXT: ret void
ret <2 x i8> %ret
}
-; TODO: The load should not have !noalias.
+; The load should not have !noalias.
define void @caller2(<2 x i8>* %ptr1, <2 x i8>* %ptr2) {
; CHECK-LABEL: @caller2(
; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
-; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !alias.scope !3, !noalias !3
+; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !alias.scope !3{{$}}
; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !3
; CHECK-NEXT: ret void
;