diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -937,50 +937,55 @@ return rv; } - // While the assume intrinsic is marked as arbitrarily writing so that - // proper control dependencies will be maintained, it never aliases any - // particular memory location. - if (isIntrinsicCall(Call, Intrinsic::assume)) - return ModRefInfo::NoModRef; - - // Like assumes, guard intrinsics are also marked as arbitrarily writing so - // that proper control dependencies are maintained but they never mods any - // particular memory location. - // - // *Unlike* assumes, guard intrinsics are modeled as reading memory since the - // heap state at the point the guard is issued needs to be consistent in case - // the guard invokes the "deopt" continuation. - if (isIntrinsicCall(Call, Intrinsic::experimental_guard)) - return ModRefInfo::Ref; - // The same applies to deoptimize which is essentially a guard(false). - if (isIntrinsicCall(Call, Intrinsic::experimental_deoptimize)) - return ModRefInfo::Ref; - - // Like assumes, invariant.start intrinsics were also marked as arbitrarily - // writing so that proper control dependencies are maintained but they never - // mod any particular memory location visible to the IR. - // *Unlike* assumes (which are now modeled as NoModRef), invariant.start - // intrinsic is now modeled as reading memory. This prevents hoisting the - // invariant.start intrinsic over stores. Consider: - // *ptr = 40; - // *ptr = 50; - // invariant_start(ptr) - // int val = *ptr; - // print(val); - // - // This cannot be transformed to: - // - // *ptr = 40; - // invariant_start(ptr) - // *ptr = 50; - // int val = *ptr; - // print(val); - // - // The transformation will cause the second store to be ignored (based on - // rules of invariant.start) and print 40, while the first program always - // prints 50. - if (isIntrinsicCall(Call, Intrinsic::invariant_start)) - return ModRefInfo::Ref; + if (const IntrinsicInst *II = dyn_cast(Call)) { + switch (II->getIntrinsicID()) { + // While these intrinsics are marked as arbitrarily writing so that + // proper control dependencies will be maintained, they never aliase any + // particular memory location. + case Intrinsic::annotation: + case Intrinsic::assume: + case Intrinsic::ptr_annotation: + case Intrinsic::var_annotation: + return ModRefInfo::NoModRef; + // Like assumes, guard intrinsics are also marked as arbitrarily writing + // so that proper control dependencies are maintained but they never mods + // any particular memory location. + // + // *Unlike* assumes, guard intrinsics are modeled as reading memory since + // the heap state at the point the guard is issued needs to be consistent + // in case the guard invokes the "deopt" continuation. + case Intrinsic::experimental_guard: + // The same applies to deoptimize which is essentially a guard(false). + case Intrinsic::experimental_deoptimize: + // Like assumes, invariant.start intrinsics were also marked as + // arbitrarily writing so that proper control dependencies are maintained + // but they never mod any particular memory location visible to the IR. + // *Unlike* assumes (which are now modeled as NoModRef), invariant.start + // intrinsic is now modeled as reading memory. This prevents hoisting the + // invariant.start intrinsic over stores. Consider: + // *ptr = 40; + // *ptr = 50; + // invariant_start(ptr) + // int val = *ptr; + // print(val); + // + // This cannot be transformed to: + // + // *ptr = 40; + // invariant_start(ptr) + // *ptr = 50; + // int val = *ptr; + // print(val); + // + // The transformation will cause the second store to be ignored (based on + // rules of invariant.start) and print 40, while the first program always + // prints 50. + case Intrinsic::invariant_start: + return ModRefInfo::Ref; + default: + break; + } + } // The AAResultBase base class has some smarts, lets use them. return AAResultBase::getModRefInfo(Call, Loc, AAQI); diff --git a/llvm/test/Transforms/InstCombine/annotation-intrinsic.ll b/llvm/test/Transforms/InstCombine/annotation-intrinsic.ll --- a/llvm/test/Transforms/InstCombine/annotation-intrinsic.ll +++ b/llvm/test/Transforms/InstCombine/annotation-intrinsic.ll @@ -13,8 +13,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[C:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.annotation.i32(i32 [[TMP0]], i8* undef, i8* undef, i32 undef) -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[C]], align 4 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP0]] ; CHECK-NEXT: ret i32 [[ADD]] ; entry: