Commit 87ddf1f4 authored by Johannes Doerfert's avatar Johannes Doerfert
Browse files

[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.
parent 1c0ebcca
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -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(...).
+35 −0
Original line number Diff line number Diff line
@@ -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
}