Index: llvm/trunk/lib/CodeGen/Analysis.cpp =================================================================== --- llvm/trunk/lib/CodeGen/Analysis.cpp +++ llvm/trunk/lib/CodeGen/Analysis.cpp @@ -519,10 +519,12 @@ AttrBuilder CalleeAttrs(cast(I)->getAttributes(), AttributeList::ReturnIndex); - // Noalias is completely benign as far as calling convention goes, it - // shouldn't affect whether the call is a tail call. + // NoAlias and NonNull are completely benign as far as calling convention + // goes, they shouldn't affect whether the call is a tail call. CallerAttrs.removeAttribute(Attribute::NoAlias); CalleeAttrs.removeAttribute(Attribute::NoAlias); + CallerAttrs.removeAttribute(Attribute::NonNull); + CalleeAttrs.removeAttribute(Attribute::NonNull); if (CallerAttrs.contains(Attribute::ZExt)) { if (!CalleeAttrs.contains(Attribute::ZExt)) Index: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp @@ -1871,15 +1871,6 @@ CallInst *CI = TailCalls[i]; CallSite CS(CI); - // Conservatively require the attributes of the call to match those of the - // return. Ignore noalias because it doesn't affect the call sequence. - AttributeList CalleeAttrs = CS.getAttributes(); - if (AttrBuilder(CalleeAttrs, AttributeList::ReturnIndex) - .removeAttribute(Attribute::NoAlias) != - AttrBuilder(CalleeAttrs, AttributeList::ReturnIndex) - .removeAttribute(Attribute::NoAlias)) - continue; - // Make sure the call instruction is followed by an unconditional branch to // the return block. BasicBlock *CallBB = CI->getParent(); Index: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -55,10 +55,12 @@ const Function &F = DAG.getMachineFunction().getFunction(); // Conservatively require the attributes of the call to match those of - // the return. Ignore noalias because it doesn't affect the call sequence. + // the return. Ignore NoAlias and NonNull because they don't affect the + // call sequence. AttributeList CallerAttrs = F.getAttributes(); if (AttrBuilder(CallerAttrs, AttributeList::ReturnIndex) .removeAttribute(Attribute::NoAlias) + .removeAttribute(Attribute::NonNull) .hasAttributes()) return false; Index: llvm/trunk/test/CodeGen/ARM/tail-call.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/tail-call.ll +++ llvm/trunk/test/CodeGen/ARM/tail-call.ll @@ -98,3 +98,15 @@ %call = tail call i32 (i32, ...) @variadic(i32 %y, i64 %z, i64 %z) ret void } + +; Check that NonNull attributes don't inhibit tailcalls. + +declare nonnull i8* @nonnull_callee(i8* %p, i32 %val) +define i8* @nonnull_caller(i8* %p, i32 %val) { +; CHECK-LABEL: nonnull_caller: +; CHECK-TAIL: b nonnull_callee +; CHECK-NO-TAIL: bl nonnull_callee +entry: + %call = tail call i8* @nonnull_callee(i8* %p, i32 %val) + ret i8* %call +} Index: llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll =================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll +++ llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll @@ -0,0 +1,77 @@ +; RUN: opt -codegenprepare -S < %s | FileCheck %s + +target triple = "armv8m.main-none-eabi" + +declare i8* @f0() +declare i8* @f1() + +define i8* @tail_dup() { +; CHECK-LABEL: tail_dup +; CHECK: tail call i8* @f0() +; CHECK-NEXT: ret i8* +; CHECK: tail call i8* @f1() +; CHECK-NEXT: ret i8* +bb0: + %tmp0 = tail call i8* @f0() + br label %return +bb1: + %tmp1 = tail call i8* @f1() + br label %return +return: + %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ] + ret i8* %retval +} + +define nonnull i8* @nonnull_dup() { +; CHECK-LABEL: nonnull_dup +; CHECK: tail call i8* @f0() +; CHECK-NEXT: ret i8* +; CHECK: tail call i8* @f1() +; CHECK-NEXT: ret i8* +bb0: + %tmp0 = tail call i8* @f0() + br label %return +bb1: + %tmp1 = tail call i8* @f1() + br label %return +return: + %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ] + ret i8* %retval +} + +define i8* @noalias_dup() { +; CHECK-LABEL: noalias_dup +; CHECK: tail call noalias i8* @f0() +; CHECK-NEXT: ret i8* +; CHECK: tail call noalias i8* @f1() +; CHECK-NEXT: ret i8* +bb0: + %tmp0 = tail call noalias i8* @f0() + br label %return +bb1: + %tmp1 = tail call noalias i8* @f1() + br label %return +return: + %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ] + ret i8* %retval +} + +; Use inreg as a way of testing that attributes (other than nonnull and +; noalias) disable the tailcall duplication in cgp. + +define inreg i8* @inreg_nodup() { +; CHECK-LABEL: inreg_nodup +; CHECK: tail call i8* @f0() +; CHECK-NEXT: br label %return +; CHECK: tail call i8* @f1() +; CHECK-NEXT: br label %return +bb0: + %tmp0 = tail call i8* @f0() + br label %return +bb1: + %tmp1 = tail call i8* @f1() + br label %return +return: + %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ] + ret i8* %retval +}