diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 4cb61feca88..c0f4b7768c3 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -1099,25 +1099,6 @@ public: /// terminator instruction that has not been predicated. virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const; - /// Returns true if MI is an unconditional tail call. - virtual bool isUnconditionalTailCall(const MachineInstr &MI) const { - return false; - } - - /// Returns true if the tail call can be made conditional on BranchCond. - virtual bool - canMakeTailCallConditional(SmallVectorImpl &Cond, - const MachineInstr &TailCall) const { - return false; - } - - /// Replace the conditional branch in MBB with a conditional tail call. - virtual void replaceBranchWithTailCall(MachineBasicBlock &MBB, - SmallVectorImpl &Cond, - const MachineInstr &TailCall) const { - llvm_unreachable("Target didn't implement replaceBranchWithTailCall!"); - } - /// Convert the instruction into a predicated instruction. /// It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr &MI, diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index c632eb7ab7d..b196bf98d27 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -49,7 +49,6 @@ STATISTIC(NumDeadBlocks, "Number of dead blocks removed"); STATISTIC(NumBranchOpts, "Number of branches optimized"); STATISTIC(NumTailMerge , "Number of block tails merged"); STATISTIC(NumHoist , "Number of times common instructions are hoisted"); -STATISTIC(NumTailCalls, "Number of tail calls optimized"); static cl::opt FlagEnableTailMerge("enable-tail-merge", cl::init(cl::BOU_UNSET), cl::Hidden); @@ -1394,42 +1393,6 @@ ReoptimizeBlock: } } - if (!IsEmptyBlock(MBB) && MBB->pred_size() == 1 && - MF.getFunction()->optForSize()) { - // Changing "Jcc foo; foo: jmp bar;" into "Jcc bar;" might change the branch - // direction, thereby defeating careful block placement and regressing - // performance. Therefore, only consider this for optsize functions. - MachineInstr &TailCall = *MBB->getFirstNonDebugInstr(); - if (TII->isUnconditionalTailCall(TailCall)) { - MachineBasicBlock *Pred = *MBB->pred_begin(); - MachineBasicBlock *PredTBB = nullptr, *PredFBB = nullptr; - SmallVector PredCond; - bool PredAnalyzable = - !TII->analyzeBranch(*Pred, PredTBB, PredFBB, PredCond, true); - - if (PredAnalyzable && !PredCond.empty() && PredTBB == MBB) { - // The predecessor has a conditional branch to this block which consists - // of only a tail call. Try to fold the tail call into the conditional - // branch. - if (TII->canMakeTailCallConditional(PredCond, TailCall)) { - // TODO: It would be nice if analyzeBranch() could provide a pointer - // to the branch insturction so replaceBranchWithTailCall() doesn't - // have to search for it. - TII->replaceBranchWithTailCall(*Pred, PredCond, TailCall); - ++NumTailCalls; - Pred->removeSuccessor(MBB); - MadeChange = true; - return MadeChange; - } - } - // If the predecessor is falling through to this block, we could reverse - // the branch condition and fold the tail call into that. However, after - // that we might have to re-arrange the CFG to fall through to the other - // block and there is a high risk of regressing code size rather than - // improving it. - } - } - // Analyze the branch in the current block. MachineBasicBlock *CurTBB = nullptr, *CurFBB = nullptr; SmallVector CurCond; diff --git a/lib/Target/X86/X86ExpandPseudo.cpp b/lib/Target/X86/X86ExpandPseudo.cpp index c4bc29e963e..6a2cf1d5314 100644 --- a/lib/Target/X86/X86ExpandPseudo.cpp +++ b/lib/Target/X86/X86ExpandPseudo.cpp @@ -77,11 +77,9 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, default: return false; case X86::TCRETURNdi: - case X86::TCRETURNdicc: case X86::TCRETURNri: case X86::TCRETURNmi: case X86::TCRETURNdi64: - case X86::TCRETURNdi64cc: case X86::TCRETURNri64: case X86::TCRETURNmi64: { bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64; @@ -99,10 +97,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, Offset = StackAdj - MaxTCDelta; assert(Offset >= 0 && "Offset should never be negative"); - if (Opcode == X86::TCRETURNdicc || Opcode == X86::TCRETURNdi64cc) { - assert(Offset == 0 && "Conditional tail call cannot adjust the stack."); - } - if (Offset) { // Check for possible merge with preceding ADD instruction. Offset += X86FL->mergeSPUpdates(MBB, MBBI, true); @@ -111,21 +105,12 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, // Jump to label or value in register. bool IsWin64 = STI->isTargetWin64(); - if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdicc || - Opcode == X86::TCRETURNdi64 || Opcode == X86::TCRETURNdi64cc) { + if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdi64) { unsigned Op; switch (Opcode) { case X86::TCRETURNdi: Op = X86::TAILJMPd; break; - case X86::TCRETURNdicc: - Op = X86::TAILJMPd_CC; - break; - case X86::TCRETURNdi64cc: - assert(!IsWin64 && "Conditional tail calls confuse the Win64 unwinder."); - // TODO: We could do it for Win64 "leaf" functions though; PR30337. - Op = X86::TAILJMPd64_CC; - break; default: // Note: Win64 uses REX prefixes indirect jumps out of functions, but // not direct ones. @@ -141,10 +126,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, MIB.addExternalSymbol(JumpTarget.getSymbolName(), JumpTarget.getTargetFlags()); } - if (Op == X86::TAILJMPd_CC || Op == X86::TAILJMPd64_CC) { - MIB.addImm(MBBI->getOperand(2).getImm()); - } - } else if (Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64) { unsigned Op = (Opcode == X86::TCRETURNmi) ? X86::TAILJMPm diff --git a/lib/Target/X86/X86InstrControl.td b/lib/Target/X86/X86InstrControl.td index 4ea223e82be..2f260c48df4 100644 --- a/lib/Target/X86/X86InstrControl.td +++ b/lib/Target/X86/X86InstrControl.td @@ -264,21 +264,6 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, "jmp{l}\t{*}$dst", [], IIC_JMP_MEM>; } -// Conditional tail calls are similar to the above, but they are branches -// rather than barriers, and they use EFLAGS. -let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1, - isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in - let Uses = [ESP, EFLAGS] in { - def TCRETURNdicc : PseudoI<(outs), - (ins i32imm_pcrel:$dst, i32imm:$offset, i32imm:$cond), []>; - - // This gets substituted to a conditional jump instruction in MC lowering. - def TAILJMPd_CC : Ii32PCRel<0x80, RawFrm, (outs), - (ins i32imm_pcrel:$dst, i32imm:$cond), - "", - [], IIC_JMP_REL>; -} - //===----------------------------------------------------------------------===// // Call Instructions... @@ -340,19 +325,3 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, "rex64 jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; } } - -// Conditional tail calls are similar to the above, but they are branches -// rather than barriers, and they use EFLAGS. -let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1, - isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in - let Uses = [RSP, EFLAGS] in { - def TCRETURNdi64cc : PseudoI<(outs), - (ins i64i32imm_pcrel:$dst, i32imm:$offset, - i32imm:$cond), []>; - - // This gets substituted to a conditional jump instruction in MC lowering. - def TAILJMPd64_CC : Ii32PCRel<0x80, RawFrm, (outs), - (ins i64i32imm_pcrel:$dst, i32imm:$cond), - "", - [], IIC_JMP_REL>; -} diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 87f4a9946f2..a9b29818505 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -5577,85 +5577,6 @@ bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { return !isPredicated(MI); } -bool X86InstrInfo::isUnconditionalTailCall(const MachineInstr &MI) const { - switch (MI.getOpcode()) { - case X86::TCRETURNdi: - case X86::TCRETURNri: - case X86::TCRETURNmi: - case X86::TCRETURNdi64: - case X86::TCRETURNri64: - case X86::TCRETURNmi64: - return true; - default: - return false; - } -} - -bool X86InstrInfo::canMakeTailCallConditional( - SmallVectorImpl &BranchCond, - const MachineInstr &TailCall) const { - if (TailCall.getOpcode() != X86::TCRETURNdi && - TailCall.getOpcode() != X86::TCRETURNdi64) { - // Only direct calls can be done with a conditional branch. - return false; - } - - if (Subtarget.isTargetWin64()) { - // Conditional tail calls confuse the Win64 unwinder. - // TODO: Allow them for "leaf" functions; PR30337. - return false; - } - - assert(BranchCond.size() == 1); - if (BranchCond[0].getImm() > X86::LAST_VALID_COND) { - // Can't make a conditional tail call with this condition. - return false; - } - - const X86MachineFunctionInfo *X86FI = - TailCall.getParent()->getParent()->getInfo(); - if (X86FI->getTCReturnAddrDelta() != 0 || - TailCall.getOperand(1).getImm() != 0) { - // A conditional tail call cannot do any stack adjustment. - return false; - } - - return true; -} - -void X86InstrInfo::replaceBranchWithTailCall( - MachineBasicBlock &MBB, SmallVectorImpl &BranchCond, - const MachineInstr &TailCall) const { - assert(canMakeTailCallConditional(BranchCond, TailCall)); - - MachineBasicBlock::iterator I = MBB.end(); - while (I != MBB.begin()) { - --I; - if (I->isDebugValue()) - continue; - if (!I->isBranch()) - assert(0 && "Can't find the branch to replace!"); - - X86::CondCode CC = getCondFromBranchOpc(I->getOpcode()); - assert(BranchCond.size() == 1); - if (CC != BranchCond[0].getImm()) - continue; - - break; - } - - unsigned Opc = TailCall.getOpcode() == X86::TCRETURNdi ? X86::TCRETURNdicc - : X86::TCRETURNdi64cc; - - auto MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opc)); - MIB->addOperand(TailCall.getOperand(0)); // Destination. - MIB.addImm(0); // Stack offset (not used). - MIB->addOperand(BranchCond[0]); // Condition. - MIB.copyImplicitOps(TailCall); // Regmask and (imp-used) parameters. - - I->eraseFromParent(); -} - // Given a MBB and its TBB, find the FBB which was a fallthrough MBB (it may // not be a fallthrough MBB now due to layout changes). Return nullptr if the // fallthrough MBB cannot be identified. diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index c2644a35e48..0d4bc5d0fb6 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -316,13 +316,6 @@ public: // Branch analysis. bool isUnpredicatedTerminator(const MachineInstr &MI) const override; - bool isUnconditionalTailCall(const MachineInstr &MI) const override; - bool canMakeTailCallConditional(SmallVectorImpl &Cond, - const MachineInstr &TailCall) const override; - void replaceBranchWithTailCall(MachineBasicBlock &MBB, - SmallVectorImpl &Cond, - const MachineInstr &TailCall) const override; - bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl &Cond, diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index 65949531126..0887643ed5a 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -499,16 +499,11 @@ ReSimplify: break; } - // TAILJMPd, TAILJMPd64, TailJMPd_cc - Lower to the correct jump instruction. + // TAILJMPd, TAILJMPd64 - Lower to the correct jump instruction. { unsigned Opcode; case X86::TAILJMPr: Opcode = X86::JMP32r; goto SetTailJmpOpcode; case X86::TAILJMPd: case X86::TAILJMPd64: Opcode = X86::JMP_1; goto SetTailJmpOpcode; - case X86::TAILJMPd_CC: - case X86::TAILJMPd64_CC: - Opcode = X86::GetCondBranchFromCond( - static_cast(MI->getOperand(1).getImm())); - goto SetTailJmpOpcode; SetTailJmpOpcode: MCOperand Saved = OutMI.getOperand(0); @@ -1299,11 +1294,9 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { case X86::TAILJMPr: case X86::TAILJMPm: case X86::TAILJMPd: - case X86::TAILJMPd_CC: case X86::TAILJMPr64: case X86::TAILJMPm64: case X86::TAILJMPd64: - case X86::TAILJMPd64_CC: case X86::TAILJMPr64_REX: case X86::TAILJMPm64_REX: // Lower these as normal, but add some comments. diff --git a/test/CodeGen/X86/conditional-tailcall.ll b/test/CodeGen/X86/conditional-tailcall.ll deleted file mode 100644 index 502643d9a91..00000000000 --- a/test/CodeGen/X86/conditional-tailcall.ll +++ /dev/null @@ -1,53 +0,0 @@ -; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s - -declare void @foo() -declare void @bar() - -define void @f(i32 %x, i32 %y) optsize { -entry: - %p = icmp eq i32 %x, %y - br i1 %p, label %bb1, label %bb2 -bb1: - tail call void @foo() - ret void -bb2: - tail call void @bar() - ret void - -; CHECK-LABEL: f: -; CHECK: cmp -; CHECK: jne bar -; Check that the asm doesn't just look good, but uses the correct encoding. -; CHECK: encoding: [0x75,A] -; CHECK: jmp foo -} - - -declare x86_thiscallcc zeroext i1 @baz(i8*, i32) -define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize { -entry: - %and = and i32 %x, 42 - %tobool = icmp eq i32 %and, 0 - br i1 %tobool, label %land.end, label %land.rhs - -land.rhs: - %and6 = and i32 %x, 44 - %tobool7 = icmp eq i32 %and6, 0 - br i1 %tobool7, label %lor.rhs, label %land.end - -lor.rhs: - %call = tail call x86_thiscallcc zeroext i1 @baz(i8* %this, i32 %x) #2 - br label %land.end - -land.end: - %0 = phi i1 [ false, %entry ], [ true, %land.rhs ], [ %call, %lor.rhs ] - ret i1 %0 - -; Make sure machine block placement isn't confused by the conditional tail call, -; but sees that it can fall through to the next block. -; CHECK-LABEL: BlockPlacementTest -; CHECK: je baz -; CHECK-NOT: xor -; CHECK: ret -} diff --git a/test/CodeGen/X86/shrink-compare.ll b/test/CodeGen/X86/shrink-compare.ll index 41f5d2d5be2..11facc4f009 100644 --- a/test/CodeGen/X86/shrink-compare.ll +++ b/test/CodeGen/X86/shrink-compare.ll @@ -93,7 +93,8 @@ if.end: ; CHECK-LABEL: test2_1: ; CHECK: movzbl ; CHECK: cmpl $256 -; CHECK: je bar +; CHECK: jne .LBB +; CHECK: jmp bar define void @test2_1(i32 %X) nounwind minsize { entry: %and = and i32 %X, 255 @@ -223,7 +224,8 @@ if.end: ; CHECK-LABEL: test_sext_i8_icmp_255: ; CHECK: movb $1, ; CHECK: testb -; CHECK: je bar +; CHECK: jne .LBB +; CHECK: jmp bar define void @test_sext_i8_icmp_255(i8 %x) nounwind minsize { entry: %sext = sext i8 %x to i32 diff --git a/test/CodeGen/X86/tail-call-conditional.mir b/test/CodeGen/X86/tail-call-conditional.mir deleted file mode 100644 index 75cb1e451d8..00000000000 --- a/test/CodeGen/X86/tail-call-conditional.mir +++ /dev/null @@ -1,85 +0,0 @@ -# RUN: llc -mtriple x86_64-- -verify-machineinstrs -run-pass branch-folder -o - %s | FileCheck %s - -# Check the TCRETURNdi64cc optimization. - ---- | - target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - - define i64 @test(i64 %arg, i8* %arg1) optsize { - %tmp = icmp ult i64 %arg, 100 - br i1 %tmp, label %1, label %4 - - %tmp3 = icmp ult i64 %arg, 10 - br i1 %tmp3, label %2, label %3 - - %tmp5 = tail call i64 @f1(i8* %arg1, i64 %arg) - ret i64 %tmp5 - - %tmp7 = tail call i64 @f2(i8* %arg1, i64 %arg) - ret i64 %tmp7 - - ret i64 123 - } - - declare i64 @f1(i8*, i64) - declare i64 @f2(i8*, i64) - -... ---- -name: test -tracksRegLiveness: true -liveins: - - { reg: '%rdi' } - - { reg: '%rsi' } -body: | - bb.0: - successors: %bb.1, %bb.4 - liveins: %rdi, %rsi - - %rax = COPY %rdi - CMP64ri8 %rax, 99, implicit-def %eflags - JA_1 %bb.4, implicit %eflags - JMP_1 %bb.1 - - ; CHECK: bb.1: - ; CHECK-NEXT: successors: %bb.2({{[^)]+}}){{$}} - ; CHECK-NEXT: liveins: %rax, %rsi - ; CHECK-NEXT: {{^ $}} - ; CHECK-NEXT: %rdi = COPY %rsi - ; CHECK-NEXT: %rsi = COPY %rax - ; CHECK-NEXT: CMP64ri8 %rax, 9, implicit-def %eflags - ; CHECK-NEXT: TCRETURNdi64cc @f1, 0, 3, csr_64, implicit %rsp, implicit %eflags, implicit %rsp, implicit %rdi, implicit %rsi - - bb.1: - successors: %bb.2, %bb.3 - liveins: %rax, %rsi - - CMP64ri8 %rax, 9, implicit-def %eflags - JA_1 %bb.3, implicit %eflags - JMP_1 %bb.2 - - bb.2: - liveins: %rax, %rsi - - %rdi = COPY %rsi - %rsi = COPY %rax - - TCRETURNdi64 @f1, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi - - ; CHECK: bb.2: - ; CHECK-NEXT: liveins: %rax, %rdi, %rsi - ; CHECK-NEXT: {{^ $}} - ; CHECK-NEXT: TCRETURNdi64 @f2, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi - - bb.3: - liveins: %rax, %rsi - - %rdi = COPY %rsi - %rsi = COPY %rax - TCRETURNdi64 @f2, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi - - bb.4: - dead %eax = MOV32ri64 123, implicit-def %rax - RET 0, %rax - -...