Commit 070af1b7 authored by Sanjay Patel's avatar Sanjay Patel
Browse files

[InstCombine] avoid crashing on attribute propagation

In https://llvm.org/PR48810 , we are crashing while trying to
propagate attributes from mempcpy (returns void*) to memcpy
(returns nothing - void).

We can avoid the crash by removing known incompatible
attributes for the void return type.

I'm not sure if this goes far enough (should we just drop all
attributes since this isn't the same function?). We also need
to audit other transforms in LibCallSimplifier to make sure
there are no other cases that have the same problem.

Differential Revision: https://reviews.llvm.org/D95088
parent 2b4716d6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1150,7 +1150,12 @@ Value *LibCallSimplifier::optimizeMemPCpy(CallInst *CI, IRBuilderBase &B) {
  // mempcpy(x, y, n) -> llvm.memcpy(align 1 x, align 1 y, n), x + n
  CallInst *NewCI =
      B.CreateMemCpy(Dst, Align(1), CI->getArgOperand(1), Align(1), N);
  // Propagate attributes, but memcpy has no return value, so make sure that
  // any return attributes are compliant.
  // TODO: Attach return value attributes to the 1st operand to preserve them?
  NewCI->setAttributes(CI->getAttributes());
  NewCI->removeAttributes(AttributeList::ReturnIndex,
                          AttributeFuncs::typeIncompatible(NewCI->getType()));
  return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N);
}

+11 −0
Original line number Diff line number Diff line
@@ -53,4 +53,15 @@ define i8* @memcpy_big_const_n(i8* %d, i8* nocapture readonly %s) {
  ret i8* %r
}

; The original call may have attributes that can not propagate to memcpy.

define i32 @PR48810() {
; CHECK-LABEL: @PR48810(
; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 undef, i8* align 536870912 null, i64 undef, i1 false)
; CHECK-NEXT:    ret i32 undef
;
  %r = call dereferenceable(1) i8* @mempcpy(i8* undef, i8* null, i64 undef)
  ret i32 undef
}

declare i8* @mempcpy(i8*, i8* nocapture readonly, i64)