Skip to content

Commit ea014c5

Browse files
committed
[Inline] Fix noalias addition on simplified instructions (PR50589)
When adding noalias/alias.scope metadata, we analyze the instructions of the original callee, and then place metadata on the corresponding inlined instructions in the caller as provided by VMap. However, this assumes that this actually a clone of the instruction, rather than the result of simplification. If simplification occurred, the instruction that VMap points to may not have any relationship as far as ModRef behavior is concerned. Fix this by tracking simplified instructions during cloning and then only processing instructions that have not been simplified. This is done with an additional map form original to cloned instruction, into which we only insert if no simplification is performed. The mapping in VMap can then be compared to this map. If they're the same, the instruction hasn't been simplified. (I originally wanted to only track a set of simplified instructions, but that wouldn't work if the instruction only gets simplified afterwards, e.g. based on rewritten phis.) Fixes https://bugs.llvm.org/show_bug.cgi?id=50589. Differential Revision: https://reviews.llvm.org/D106242
1 parent e8bc871 commit ea014c5

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

llvm/include/llvm/Transforms/Utils/Cloning.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,16 @@ struct ClonedCodeInfo {
7575
/// originally inserted callsites were DCE'ed after they were cloned.
7676
std::vector<WeakTrackingVH> OperandBundleCallSites;
7777

78+
/// Like VMap, but maps only unsimplified instructions. Values in the map
79+
/// may be dangling, it is only intended to be used via isSimplified(), to
80+
/// check whether the main VMap mapping involves simplification or not.
81+
DenseMap<const Value *, const Value *> OrigVMap;
82+
7883
ClonedCodeInfo() = default;
84+
85+
bool isSimplified(const Value *From, const Value *To) const {
86+
return OrigVMap.lookup(From) != To;
87+
}
7988
};
8089

8190
/// Return a copy of the specified basic block, but without

llvm/lib/Transforms/Utils/CloneFunction.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,12 @@ void PruningFunctionCloner::CloneBlock(
412412
NewBB->getInstList().push_back(NewInst);
413413
hasCalls |= (isa<CallInst>(II) && !isa<DbgInfoIntrinsic>(II));
414414

415-
if (CodeInfo)
415+
if (CodeInfo) {
416+
CodeInfo->OrigVMap[&*II] = NewInst;
416417
if (auto *CB = dyn_cast<CallBase>(&*II))
417418
if (CB->hasOperandBundles())
418419
CodeInfo->OperandBundleCallSites.push_back(NewInst);
420+
}
419421

420422
if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
421423
if (isa<ConstantInt>(AI->getArraySize()))
@@ -469,10 +471,12 @@ void PruningFunctionCloner::CloneBlock(
469471
NewBB->getInstList().push_back(NewInst);
470472
VMap[OldTI] = NewInst; // Add instruction map to value.
471473

472-
if (CodeInfo)
474+
if (CodeInfo) {
475+
CodeInfo->OrigVMap[OldTI] = NewInst;
473476
if (auto *CB = dyn_cast<CallBase>(OldTI))
474477
if (CB->hasOperandBundles())
475478
CodeInfo->OperandBundleCallSites.push_back(NewInst);
479+
}
476480

477481
// Recursively clone any reachable successor blocks.
478482
append_range(ToClone, successors(BB->getTerminator()));

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ void ScopedAliasMetadataDeepCloner::remap(Function::iterator FStart,
939939
/// parameters with noalias metadata specifying the new scope, and tag all
940940
/// non-derived loads, stores and memory intrinsics with the new alias scopes.
941941
static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
942-
const DataLayout &DL, AAResults *CalleeAAR) {
942+
const DataLayout &DL, AAResults *CalleeAAR,
943+
ClonedCodeInfo &InlinedFunctionInfo) {
943944
if (!EnableNoAliasConversion)
944945
return;
945946

@@ -1009,7 +1010,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
10091010
continue;
10101011

10111012
Instruction *NI = dyn_cast<Instruction>(VMI->second);
1012-
if (!NI)
1013+
if (!NI || InlinedFunctionInfo.isSimplified(I, NI))
10131014
continue;
10141015

10151016
bool IsArgMemOnlyCall = false, IsFuncCall = false;
@@ -2037,7 +2038,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
20372038
SAMetadataCloner.remap(FirstNewBlock, Caller->end());
20382039

20392040
// Add noalias metadata if necessary.
2040-
AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR);
2041+
AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR, InlinedFunctionInfo);
20412042

20422043
// Clone return attributes on the callsite into the calls within the inlined
20432044
// function which feed into its return value.

llvm/test/Transforms/Inline/pr50589.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ define <2 x i8> @callee1(<2 x i8>* %ptr1, <2 x i8>* noalias %ptr2, <2 x i1> %mas
1515
ret <2 x i8> %ret
1616
}
1717

18-
; TODO: The load should not have !noalias.
18+
; The load should not have !noalias.
1919
define void @caller1(<2 x i8>* %ptr1, <2 x i8>* %ptr2) {
2020
; CHECK-LABEL: @caller1(
21-
; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !noalias !0
21+
; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2{{$}}
2222
; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
2323
; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !0
2424
; CHECK-NEXT: ret void
@@ -41,11 +41,11 @@ define <2 x i8> @callee2(<2 x i8>* %ptr1, <2 x i8>* noalias %ptr2, <2 x i1> %mas
4141
ret <2 x i8> %ret
4242
}
4343

44-
; TODO: The load should not have !noalias.
44+
; The load should not have !noalias.
4545
define void @caller2(<2 x i8>* %ptr1, <2 x i8>* %ptr2) {
4646
; CHECK-LABEL: @caller2(
4747
; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
48-
; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !alias.scope !3, !noalias !3
48+
; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !alias.scope !3{{$}}
4949
; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !3
5050
; CHECK-NEXT: ret void
5151
;

0 commit comments

Comments
 (0)