forked from OSchip/llvm-project
X86: Conditional tail calls should not have isBarrier = 1
That confuses e.g. machine basic block placement, which then doesn't realize that control can fall through a block that ends with a conditional tail call. Instead, isBranch=1 should be set. Also, mark EFLAGS as used by these instructions. llvm-svn: 281281
This commit is contained in:
parent
04c7db31e8
commit
8a42d4b9cc
|
@ -239,14 +239,11 @@ let isCall = 1 in
|
|||
|
||||
|
||||
// Tail call stuff.
|
||||
|
||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
||||
isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in
|
||||
let Uses = [ESP] in {
|
||||
def TCRETURNdi : PseudoI<(outs),
|
||||
(ins i32imm_pcrel:$dst, i32imm:$offset), []>;
|
||||
def TCRETURNdicc : PseudoI<(outs),
|
||||
(ins i32imm_pcrel:$dst, i32imm:$offset, i32imm:$cond), []>;
|
||||
def TCRETURNri : PseudoI<(outs),
|
||||
(ins ptr_rc_tailcall:$dst, i32imm:$offset), []>;
|
||||
let mayLoad = 1 in
|
||||
|
@ -260,12 +257,6 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
|||
"jmp\t$dst",
|
||||
[], IIC_JMP_REL>;
|
||||
|
||||
// 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>;
|
||||
|
||||
def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
|
||||
"", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is dead.
|
||||
let mayLoad = 1 in
|
||||
|
@ -273,6 +264,21 @@ 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...
|
||||
|
@ -308,9 +314,6 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
|||
def TCRETURNdi64 : PseudoI<(outs),
|
||||
(ins i64i32imm_pcrel:$dst, i32imm:$offset),
|
||||
[]>;
|
||||
def TCRETURNdi64cc : PseudoI<(outs),
|
||||
(ins i64i32imm_pcrel:$dst, i32imm:$offset,
|
||||
i32imm:$cond), []>;
|
||||
def TCRETURNri64 : PseudoI<(outs),
|
||||
(ins ptr_rc_tailcall:$dst, i32imm:$offset), []>;
|
||||
let mayLoad = 1 in
|
||||
|
@ -320,12 +323,6 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
|||
def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs), (ins i64i32imm_pcrel:$dst),
|
||||
"jmp\t$dst", [], IIC_JMP_REL>;
|
||||
|
||||
// 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>;
|
||||
|
||||
def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
|
||||
"jmp{q}\t{*}$dst", [], IIC_JMP_MEM>;
|
||||
|
||||
|
@ -343,3 +340,19 @@ 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>;
|
||||
}
|
||||
|
|
|
@ -14,12 +14,40 @@ bb1:
|
|||
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
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ body: |
|
|||
; 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 %rsp, implicit %rdi, implicit %rsi
|
||||
; 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
|
||||
|
|
Loading…
Reference in New Issue