[Attributor] Simple casts preserve no-alias property

This is a minimal but important advancement over the existing code. A
cast with an operand that is only used in the cast retains the no-alias
property of the operand.
This commit is contained in:
Johannes Doerfert 2020-01-25 20:21:41 -06:00
parent 1c0ebcca6e
commit 87ddf1f4fa
2 changed files with 53 additions and 2 deletions

View File

@ -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<CastInst>(Val);
if (!CI)
break;
Value *Base = CI->getOperand(0);
if (Base->getNumUses() != 1)
break;
Val = Base;
} while (true);
if (isa<AllocaInst>(Val))
indicateOptimisticFixpoint();
else if (isa<ConstantPointerNull>(Val) &&
!NullPointerIsDefined(getAnchorScope(),
Val.getType()->getPointerAddressSpace()))
Val->getType()->getPointerAddressSpace()))
indicateOptimisticFixpoint();
else if (Val != &getAssociatedValue()) {
const auto &ValNoAliasAA =
A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
if (ValNoAliasAA.isKnownNoAlias())
indicateOptimisticFixpoint();
}
}
/// See AbstractAttribute::updateImpl(...).

View File

@ -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
}