diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 91eb561901c0cd75499124480fb9605ab5cba76f..31a7e93b239adeb1af8ac673579ef09b03d8b638 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2496,13 +2496,29 @@ struct AANoAliasFloating final : AANoAliasImpl { /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { AANoAliasImpl::initialize(A); - Value &Val = getAssociatedValue(); + Value *Val = &getAssociatedValue(); + do { + CastInst *CI = dyn_cast(Val); + if (!CI) + break; + Value *Base = CI->getOperand(0); + if (Base->getNumUses() != 1) + break; + Val = Base; + } while (true); + if (isa(Val)) indicateOptimisticFixpoint(); else if (isa(Val) && !NullPointerIsDefined(getAnchorScope(), - Val.getType()->getPointerAddressSpace())) + Val->getType()->getPointerAddressSpace())) indicateOptimisticFixpoint(); + else if (Val != &getAssociatedValue()) { + const auto &ValNoAliasAA = + A.getAAFor(*this, IRPosition::value(*Val)); + if (ValNoAliasAA.isKnownNoAlias()) + indicateOptimisticFixpoint(); + } } /// See AbstractAttribute::updateImpl(...). diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll index f22b66a12d1ff277e28e1f0b73ff4253fcd92057..0e95d546ea952fbfb7dcd39ddef3d00f02099053 100644 --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -40,6 +40,13 @@ define i8* @return_noalias_looks_like_capture(){ ret i8* %1 } +; CHECK: define noalias i16* @return_noalias_casted() +define i16* @return_noalias_casted(){ + %1 = tail call noalias i8* @malloc(i64 4) + %c = bitcast i8* %1 to i16* + ret i16* %c +} + declare i8* @alias() ; TEST 3 @@ -294,3 +301,31 @@ define void @test12_4(){ tail call void @two_args(i8* %A_0, i8* %B_0) ret void } + +; TEST 13 +define void @use_i8_internal(i8* %a) { + call void @use_i8(i8* %a) + ret void +} + +define void @test13_use_noalias(){ + %m1 = tail call noalias i8* @malloc(i64 4) + %c1 = bitcast i8* %m1 to i16* + %c2 = bitcast i16* %c1 to i8* +; CHECK: call void @use_i8_internal(i8* noalias nocapture %c2) + call void @use_i8_internal(i8* %c2) + ret void +} + +define void @test13_use_alias(){ + %m1 = tail call noalias i8* @malloc(i64 4) + %c1 = bitcast i8* %m1 to i16* + %c2a = bitcast i16* %c1 to i8* + %c2b = bitcast i16* %c1 to i8* +; CHECK: call void @use_i8_internal(i8* nocapture %c2a) +; CHECK: call void @use_i8_internal(i8* nocapture %c2b) + call void @use_i8_internal(i8* %c2a) + call void @use_i8_internal(i8* %c2b) + ret void +} +