Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -5653,6 +5653,17 @@ MIB->addOperand(BranchCond[0]); // Condition. MIB.copyImplicitOps(TailCall); // Regmask and (imp-used) parameters. + // Add implicit uses of all live regs potentially clobbered by the call. This + // way they are still live up to the call. + LivePhysRegs LiveRegs(&getRegisterInfo()); + LiveRegs.addLiveOuts(MBB); + SmallVector, 8> Clobbers; + LiveRegs.stepForward(*MIB, Clobbers); + for (const auto &C : Clobbers) { + MIB->addOperand(MachineOperand::CreateReg(C.first, /*isDef*/ false, + /*isImplicit*/ true)); + } + I->eraseFromParent(); } Index: test/CodeGen/X86/conditional-tailcall.ll =================================================================== --- test/CodeGen/X86/conditional-tailcall.ll +++ test/CodeGen/X86/conditional-tailcall.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32 +; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64 declare void @foo() declare void @bar() @@ -51,3 +51,90 @@ ; CHECK-NOT: xor ; CHECK: ret } + + + +%"class.std::basic_string" = type { %"struct.std::basic_string, std::allocator >::_Alloc_hider" } +%"struct.std::basic_string, std::allocator >::_Alloc_hider" = type { i8* } +declare zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8*, i8*) + +define zeroext i1 @pr31257(%"class.std::basic_string"* nocapture readonly dereferenceable(8) %s) minsize { +; CHECK-LABEL: pr31257 +entry: + %_M_p.i.i = getelementptr inbounds %"class.std::basic_string", %"class.std::basic_string"* %s, i64 0, i32 0, i32 0 + %0 = load i8*, i8** %_M_p.i.i, align 8 + %arrayidx.i.i.i54 = getelementptr inbounds i8, i8* %0, i64 -24 + %_M_length.i.i55 = bitcast i8* %arrayidx.i.i.i54 to i64* + %1 = load i64, i64* %_M_length.i.i55, align 8 + %add.ptr.i56 = getelementptr inbounds i8, i8* %0, i64 %1 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %it.sroa.0.0 = phi i8* [ %0, %entry ], [ %incdec.ptr.i, %for.inc ] + %state.0 = phi i32 [ 0, %entry ], [ %state.1, %for.inc ] + %cmp.i = icmp eq i8* %it.sroa.0.0, %add.ptr.i56 + br i1 %cmp.i, label %5, label %for.body + +for.body: ; preds = %for.cond + switch i32 %state.0, label %for.inc [ + i32 0, label %sw.bb + i32 1, label %sw.bb14 + i32 2, label %sw.bb22 + ] + +sw.bb: ; preds = %for.body + %2 = load i8, i8* %it.sroa.0.0, align 1 + switch i8 %2, label %if.else [ + i8 43, label %for.inc + i8 45, label %for.inc + ] + +if.else: ; preds = %sw.bb + %conv9 = zext i8 %2 to i32 + %isdigittmp45 = add nsw i32 %conv9, -48 + %isdigit46 = icmp ult i32 %isdigittmp45, 10 + br i1 %isdigit46, label %for.inc, label %cleanup.thread.loopexit + +sw.bb14: ; preds = %for.body + %3 = load i8, i8* %it.sroa.0.0, align 1 + %conv16 = zext i8 %3 to i32 + %isdigittmp43 = add nsw i32 %conv16, -48 + %isdigit44 = icmp ult i32 %isdigittmp43, 10 + br i1 %isdigit44, label %for.inc, label %cleanup.thread.loopexit + +sw.bb22: ; preds = %for.body + %4 = load i8, i8* %it.sroa.0.0, align 1 + %conv24 = zext i8 %4 to i32 + %isdigittmp = add nsw i32 %conv24, -48 + %isdigit = icmp ult i32 %isdigittmp, 10 + br i1 %isdigit, label %for.inc, label %if.else28 + +; Make sure Machine Copy Propagation doesn't delete the mov to %ecx becaue it +; thinks the conditional tail call clobbers it. +; CHECK64-LABEL: .LBB2_11: +; CHECK64: movzbl (%rdi), %ecx +; CHECK64-NEXT: addl $-48, %ecx +; CHECK64-NEXT: cmpl $10, %ecx +; CHECK64-NEXT: movl %r9d, %ecx +; CHECK64-NEXT: jae _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEE + +if.else28: ; preds = %sw.bb22 + %call34 = tail call zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8* nonnull %it.sroa.0.0, i8* %add.ptr.i56) + br label %cleanup.thread + +for.inc: ; preds = %sw.bb, %sw.bb, %sw.bb22, %sw.bb14, %if.else, %for.body + %state.1 = phi i32 [ %state.0, %for.body ], [ 1, %sw.bb ], [ 2, %if.else ], [ 2, %sw.bb14 ], [ 2, %sw.bb22 ], [ 1, %sw.bb ] + %incdec.ptr.i = getelementptr inbounds i8, i8* %it.sroa.0.0, i64 1 + br label %for.cond + +;