From ea7c99472dec39d6ffd4fde2832489a325258fb1 Mon Sep 17 00:00:00 2001 From: Michael Kuperstein Date: Tue, 11 Aug 2015 08:06:44 +0000 Subject: [PATCH] [GMR] Be a bit smarter about which globals don't alias when doing recursive lookups Should hopefully fix the remainder of PR24288. Differential Revision: http://reviews.llvm.org/D11900 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244575 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/IPA/GlobalsModRef.cpp | 30 ++++++++++++++----- .../GlobalsModRef/nonescaping-noalias.ll | 11 ++++--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index f7b55c2cf8f..f429603da0b 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -717,12 +717,23 @@ bool GlobalsModRef::isNonEscapingGlobalNoAlias(const GlobalValue *GV, if (InputGV == GV) return false; - // FIXME: It would be good to handle other obvious no-alias cases here, but - // it isn't clear how to do so reasonbly without building a small version - // of BasicAA into this code. We could recurse into AliasAnalysis::alias - // here but that seems likely to go poorly as we're inside the - // implementation of such a query. Until then, just conservatievly retun - // false. + // Distinct GlobalVariables never alias, unless overriden or zero-sized. + // FIXME: The condition can be refined, but be conservative for now. + auto *GVar = dyn_cast(GV); + auto *InputGVar = dyn_cast(InputGV); + if (GVar && InputGVar && + !GVar->isDeclaration() && !InputGVar->isDeclaration() && + !GVar->mayBeOverridden() && !InputGVar->mayBeOverridden()) { + Type *GVType = GVar->getInitializer()->getType(); + Type *InputGVType = InputGVar->getInitializer()->getType(); + if (GVType->isSized() && InputGVType->isSized() && + (DL->getTypeAllocSize(GVType) > 0) && + (DL->getTypeAllocSize(InputGVType) > 0)) + continue; + } + + // Conservatively return false, even though we could be smarter + // (e.g. look through GlobalAliases). return false; } @@ -767,7 +778,12 @@ bool GlobalsModRef::isNonEscapingGlobalNoAlias(const GlobalValue *GV, continue; } - // Unknown instruction, bail. + // FIXME: It would be good to handle other obvious no-alias cases here, but + // it isn't clear how to do so reasonbly without building a small version + // of BasicAA into this code. We could recurse into AliasAnalysis::alias + // here but that seems likely to go poorly as we're inside the + // implementation of such a query. Until then, just conservatievly retun + // false. return false; } while (!Inputs.empty()); diff --git a/test/Analysis/GlobalsModRef/nonescaping-noalias.ll b/test/Analysis/GlobalsModRef/nonescaping-noalias.ll index 11e9a6a98a1..a3f50837208 100644 --- a/test/Analysis/GlobalsModRef/nonescaping-noalias.ll +++ b/test/Analysis/GlobalsModRef/nonescaping-noalias.ll @@ -61,7 +61,9 @@ entry: ret i32 %v } -define i32 @test4(i32* %param, i32 %n, i1 %c1, i1 %c2) { +@g3 = internal global i32 1 + +define i32 @test4(i32* %param, i32 %n, i1 %c1, i1 %c2, i1 %c3) { ; Ensure that we can fold a store to a load of a global across a store to ; the pointer loaded from that global even when the load is behind PHIs and ; selects, and there is a mixture of a load and another global or argument. @@ -77,14 +79,15 @@ entry: store i32 42, i32* @g1 %ptr1 = load i32*, i32** @g2 %ptr2 = select i1 %c1, i32* %ptr1, i32* %param + %ptr3 = select i1 %c3, i32* %ptr2, i32* @g3 br label %loop loop: %iv = phi i32 [ 0, %entry ], [ %inc, %loop ] - %ptr = phi i32* [ %ptr2, %entry ], [ %ptr4, %loop ] + %ptr = phi i32* [ %ptr3, %entry ], [ %ptr5, %loop ] store i32 7, i32* %ptr - %ptr3 = load i32*, i32** @g2 - %ptr4 = select i1 %c2, i32* %ptr3, i32* %call + %ptr4 = load i32*, i32** @g2 + %ptr5 = select i1 %c2, i32* %ptr4, i32* %call %inc = add i32 %iv, 1 %test = icmp slt i32 %inc, %n br i1 %test, label %loop, label %exit -- 2.34.1