Index: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp =================================================================== --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp @@ -717,12 +717,23 @@ 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 @@ 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()); Index: llvm/trunk/test/Analysis/GlobalsModRef/nonescaping-noalias.ll =================================================================== --- llvm/trunk/test/Analysis/GlobalsModRef/nonescaping-noalias.ll +++ llvm/trunk/test/Analysis/GlobalsModRef/nonescaping-noalias.ll @@ -61,7 +61,9 @@ 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 @@ 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