diff options
| author | Johannes Doerfert <johannes@jdoerfert.de> | 2019-10-29 11:46:00 -0500 |
|---|---|---|
| committer | Johannes Doerfert <johannes@jdoerfert.de> | 2019-10-31 14:47:06 -0500 |
| commit | 2d6d651e8cb62fc5f17782c37dcad0b7bf18a4e6 (patch) | |
| tree | e68e597cf0eb3d774af71677e7c2ced5fa57ae81 | |
| parent | 57dd4b03e4806bbb4760ab6150940150d884df20 (diff) | |
| download | bcm5719-llvm-2d6d651e8cb62fc5f17782c37dcad0b7bf18a4e6.tar.gz bcm5719-llvm-2d6d651e8cb62fc5f17782c37dcad0b7bf18a4e6.zip | |
[Attributor] Make AANonNull perform context sensitive queries
Summary:
In order to get context sensitivity from isKnownNonZero we need to
provide a context instruction *and* a dominator tree. The latter is
passed now to which actually allows to remove some initialization code.
Tests taken from PR43833.
Reviewers: uenoku, sstefan1
Subscribers: hiraditya, bollu, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69595
| -rw-r--r-- | llvm/include/llvm/Transforms/IPO/Attributor.h | 6 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 27 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/nonnull.ll | 95 |
3 files changed, 106 insertions, 22 deletions
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index d952ae674f2..3366a98f631 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -608,6 +608,12 @@ struct InformationCache { return AG.getAnalysis<AAManager>(F); } + /// Return the analysis result from a pass \p AP for function \p F. + template <typename AP> + typename AP::Result *getAnalysisResultForFunction(const Function &F) { + return AG.getAnalysis<AP>(F); + } + /// Return SCC size on call graph for function \p F. unsigned getSccSize(const Function &F) { if (!SccSizeOpt.hasValue()) diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 64a42907b57..ca0ff3ab03e 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1616,24 +1616,6 @@ struct AANonNullFloating using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>; AANonNullFloating(const IRPosition &IRP) : Base(IRP) {} - /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A) override { - Base::initialize(A); - - if (isAtFixpoint()) - return; - - const IRPosition &IRP = getIRPosition(); - const Value &V = IRP.getAssociatedValue(); - const DataLayout &DL = A.getDataLayout(); - - // TODO: This context sensitive query should be removed once we can do - // context sensitive queries in the genericValueTraversal below. - if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(), - /* TODO: DT */ nullptr)) - indicateOptimisticFixpoint(); - } - /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { ChangeStatus Change = Base::updateImpl(A); @@ -1648,13 +1630,16 @@ struct AANonNullFloating const DataLayout &DL = A.getDataLayout(); + DominatorTree *DT = nullptr; + InformationCache &InfoCache = A.getInfoCache(); + if (const Function *Fn = getAnchorScope()) + DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); + auto VisitValueCB = [&](Value &V, AANonNull::StateType &T, bool Stripped) -> bool { const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V)); if (!Stripped && this == &AA) { - if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, - /* CtxI */ getCtxI(), - /* TODO: DT */ nullptr)) + if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT)) T.indicatePessimisticFixpoint(); } else { // Use abstract attribute information. diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll index fb62e4aafac..cea4785d058 100644 --- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll +++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll @@ -207,7 +207,7 @@ bb1: ; preds = %bb bb4: ; preds = %bb1 %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1 -; ATTRIBUTOR: %tmp5b = tail call i32* @f3(i32* nonnull %tmp5) +; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nonnull %tmp5) %tmp5b = tail call i32* @f3(i32* %tmp5) %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1 br label %bb9 @@ -803,5 +803,98 @@ hd2: br i1 %tmp9, label %ex, label %hd } +; Original from PR43833 +declare void @sink(i32*) + +; FIXME: the sink argument should be marked nonnull as in @PR43833_simple. +define void @PR43833(i32* %0, i32 %1) { +; BOTH-LABEL: @PR43833( +; BOTH-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1:%.*]], 1 +; BOTH-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] +; BOTH: 4: +; BOTH-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 +; BOTH-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]] +; BOTH-NEXT: br label [[TMP8:%.*]] +; BOTH: 7: +; BOTH-NEXT: ret void +; BOTH: 8: +; BOTH-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] +; BOTH-NEXT: tail call void @sink(i32* [[TMP6]]) +; BOTH-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 +; BOTH-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] +; BOTH-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] +; + %3 = icmp sgt i32 %1, 1 + br i1 %3, label %4, label %7 + +4: ; preds = %2 + %5 = zext i32 %1 to i64 + %6 = getelementptr inbounds i32, i32* %0, i64 %5 + br label %8 + +7: ; preds = %8, %2 + ret void + +8: ; preds = %8, %4 + %9 = phi i32 [ 1, %4 ], [ %10, %8 ] + tail call void @sink(i32* %6) + %10 = add nuw nsw i32 %9, 1 + %11 = icmp eq i32 %10, %1 + br i1 %11, label %7, label %8 +} + +; Adjusted from PR43833 +define void @PR43833_simple(i32* %0, i32 %1) { +; OLD-LABEL: @PR43833_simple( +; OLD-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0 +; OLD-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] +; OLD: 4: +; OLD-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 +; OLD-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]] +; OLD-NEXT: br label [[TMP8:%.*]] +; OLD: 7: +; OLD-NEXT: ret void +; OLD: 8: +; OLD-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] +; OLD-NEXT: tail call void @sink(i32* [[TMP6]]) +; OLD-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 +; OLD-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] +; OLD-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] +; +; ATTRIBUTOR_NPM-LABEL: @PR43833_simple( +; ATTRIBUTOR_NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0 +; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] +; ATTRIBUTOR_NPM: 4: +; ATTRIBUTOR_NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 +; ATTRIBUTOR_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]] +; ATTRIBUTOR_NPM-NEXT: br label [[TMP8:%.*]] +; ATTRIBUTOR_NPM: 7: +; ATTRIBUTOR_NPM-NEXT: ret void +; ATTRIBUTOR_NPM: 8: +; ATTRIBUTOR_NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] +; ATTRIBUTOR_NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]]) +; ATTRIBUTOR_NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 +; ATTRIBUTOR_NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] +; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] +; + %3 = icmp ne i32 %1, 0 + br i1 %3, label %4, label %7 + +4: ; preds = %2 + %5 = zext i32 %1 to i64 + %6 = getelementptr inbounds i32, i32* %0, i64 %5 + br label %8 + +7: ; preds = %8, %2 + ret void + +8: ; preds = %8, %4 + %9 = phi i32 [ 1, %4 ], [ %10, %8 ] + tail call void @sink(i32* %6) + %10 = add nuw nsw i32 %9, 1 + %11 = icmp eq i32 %10, %1 + br i1 %11, label %7, label %8 +} + attributes #0 = { "null-pointer-is-valid"="true" } attributes #1 = { nounwind willreturn} |

