[X86][X87] Tag FCMOV instruction scheduler classes

llvm-svn: 319804
This commit is contained in:
Simon Pilgrim 2017-12-05 18:01:26 +00:00
parent d9500bc533
commit 65f805fe30
5 changed files with 79 additions and 73 deletions

View File

@ -356,28 +356,31 @@ def FBLDm : FPI<0xDF, MRM4m, (outs), (ins f80mem:$src), "fbld\t$src">;
def FBSTPm : FPI<0xDF, MRM6m, (outs), (ins f80mem:$dst), "fbstp\t$dst">; def FBSTPm : FPI<0xDF, MRM6m, (outs), (ins f80mem:$dst), "fbstp\t$dst">;
// Floating point cmovs. // Floating point cmovs.
class FpIf32CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> : class FpIf32CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern,
FpI_<outs, ins, fp, pattern>, Requires<[FPStackf32, HasCMov]>; InstrItinClass itin> :
class FpIf64CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> : FpI_<outs, ins, fp, pattern, itin>, Requires<[FPStackf32, HasCMov]>;
FpI_<outs, ins, fp, pattern>, Requires<[FPStackf64, HasCMov]>; class FpIf64CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern,
InstrItinClass itin> :
FpI_<outs, ins, fp, pattern, itin>, Requires<[FPStackf64, HasCMov]>;
multiclass FPCMov<PatLeaf cc> { multiclass FPCMov<PatLeaf cc> {
def _Fp32 : FpIf32CMov<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2), def _Fp32 : FpIf32CMov<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2),
CondMovFP, CondMovFP,
[(set RFP32:$dst, (X86cmov RFP32:$src1, RFP32:$src2, [(set RFP32:$dst, (X86cmov RFP32:$src1, RFP32:$src2,
cc, EFLAGS))]>; cc, EFLAGS))], IIC_FCMOV>;
def _Fp64 : FpIf64CMov<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2), def _Fp64 : FpIf64CMov<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2),
CondMovFP, CondMovFP,
[(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2, [(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2,
cc, EFLAGS))]>; cc, EFLAGS))], IIC_FCMOV>;
def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2), def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2),
CondMovFP, CondMovFP,
[(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2, [(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2,
cc, EFLAGS))]>, cc, EFLAGS))], IIC_FCMOV>,
Requires<[HasCMov]>; Requires<[HasCMov]>;
} }
let Defs = [FPSW] in { let Defs = [FPSW] in {
let SchedRW = [WriteFAdd] in {
let Uses = [EFLAGS], Constraints = "$src1 = $dst" in { let Uses = [EFLAGS], Constraints = "$src1 = $dst" in {
defm CMOVB : FPCMov<X86_COND_B>; defm CMOVB : FPCMov<X86_COND_B>;
defm CMOVBE : FPCMov<X86_COND_BE>; defm CMOVBE : FPCMov<X86_COND_BE>;
@ -392,22 +395,23 @@ defm CMOVNP : FPCMov<X86_COND_NP>;
let Predicates = [HasCMov] in { let Predicates = [HasCMov] in {
// These are not factored because there's no clean way to pass DA/DB. // These are not factored because there's no clean way to pass DA/DB.
def CMOVB_F : FPI<0xDA, MRM0r, (outs), (ins RST:$op), def CMOVB_F : FPI<0xDA, MRM0r, (outs), (ins RST:$op),
"fcmovb\t{$op, %st(0)|st(0), $op}">; "fcmovb\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVBE_F : FPI<0xDA, MRM2r, (outs), (ins RST:$op), def CMOVBE_F : FPI<0xDA, MRM2r, (outs), (ins RST:$op),
"fcmovbe\t{$op, %st(0)|st(0), $op}">; "fcmovbe\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVE_F : FPI<0xDA, MRM1r, (outs), (ins RST:$op), def CMOVE_F : FPI<0xDA, MRM1r, (outs), (ins RST:$op),
"fcmove\t{$op, %st(0)|st(0), $op}">; "fcmove\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVP_F : FPI<0xDA, MRM3r, (outs), (ins RST:$op), def CMOVP_F : FPI<0xDA, MRM3r, (outs), (ins RST:$op),
"fcmovu\t{$op, %st(0)|st(0), $op}">; "fcmovu\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVNB_F : FPI<0xDB, MRM0r, (outs), (ins RST:$op), def CMOVNB_F : FPI<0xDB, MRM0r, (outs), (ins RST:$op),
"fcmovnb\t{$op, %st(0)|st(0), $op}">; "fcmovnb\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVNBE_F: FPI<0xDB, MRM2r, (outs), (ins RST:$op), def CMOVNBE_F: FPI<0xDB, MRM2r, (outs), (ins RST:$op),
"fcmovnbe\t{$op, %st(0)|st(0), $op}">; "fcmovnbe\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVNE_F : FPI<0xDB, MRM1r, (outs), (ins RST:$op), def CMOVNE_F : FPI<0xDB, MRM1r, (outs), (ins RST:$op),
"fcmovne\t{$op, %st(0)|st(0), $op}">; "fcmovne\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
def CMOVNP_F : FPI<0xDB, MRM3r, (outs), (ins RST:$op), def CMOVNP_F : FPI<0xDB, MRM3r, (outs), (ins RST:$op),
"fcmovnu\t{$op, %st(0)|st(0), $op}">; "fcmovnu\t{$op, %st(0)|st(0), $op}", IIC_FCMOV>;
} // Predicates = [HasCMov] } // Predicates = [HasCMov]
} // SchedRW
// Floating point loads & stores. // Floating point loads & stores.
let canFoldAsLoad = 1 in { let canFoldAsLoad = 1 in {

View File

@ -447,6 +447,7 @@ def IIC_CMPX_LOCK_16B : InstrItinClass;
def IIC_XADD_LOCK_MEM : InstrItinClass; def IIC_XADD_LOCK_MEM : InstrItinClass;
def IIC_XADD_LOCK_MEM8 : InstrItinClass; def IIC_XADD_LOCK_MEM8 : InstrItinClass;
def IIC_FCMOV : InstrItinClass;
def IIC_FILD : InstrItinClass; def IIC_FILD : InstrItinClass;
def IIC_FLD : InstrItinClass; def IIC_FLD : InstrItinClass;
def IIC_FLD80 : InstrItinClass; def IIC_FLD80 : InstrItinClass;

View File

@ -364,6 +364,7 @@ def AtomItineraries : ProcessorItineraries<
InstrItinData<IIC_FST80, [InstrStage<5, [Port0, Port1]>] >, InstrItinData<IIC_FST80, [InstrStage<5, [Port0, Port1]>] >,
InstrItinData<IIC_FIST, [InstrStage<6, [Port0, Port1]>] >, InstrItinData<IIC_FIST, [InstrStage<6, [Port0, Port1]>] >,
InstrItinData<IIC_FCMOV, [InstrStage<9, [Port0, Port1]>] >,
InstrItinData<IIC_FLDZ, [InstrStage<1, [Port0, Port1]>] >, InstrItinData<IIC_FLDZ, [InstrStage<1, [Port0, Port1]>] >,
InstrItinData<IIC_FUCOM, [InstrStage<1, [Port1]>] >, InstrItinData<IIC_FUCOM, [InstrStage<1, [Port1]>] >,
InstrItinData<IIC_FUCOMI, [InstrStage<9, [Port0, Port1]>] >, InstrItinData<IIC_FUCOMI, [InstrStage<9, [Port0, Port1]>] >,

View File

@ -761,7 +761,7 @@ def : InstRW<[ZnWriteFPU3], (instregex "LD_F1")>;
// FLDPI FLDL2E etc. // FLDPI FLDL2E etc.
def : InstRW<[ZnWriteFPU3], (instregex "FLDPI", "FLDL2(T|E)" "FLDL(G|N)2")>; def : InstRW<[ZnWriteFPU3], (instregex "FLDPI", "FLDL2(T|E)" "FLDL(G|N)2")>;
def : InstRW<[WriteMicrocoded], (instregex "CMOV(B|BE|P|NB|NBE|NE|NP)_F")>; def : InstRW<[WriteMicrocoded], (instregex "CMOV(B|BE|E|P|NB|NBE|NE|NP)_F")>;
// FNSTSW. // FNSTSW.
// AX. // AX.

View File

@ -596,28 +596,28 @@ define void @test_fcmov() optsize {
; ATOM-LABEL: test_fcmov: ; ATOM-LABEL: test_fcmov:
; ATOM: # %bb.0: ; ATOM: # %bb.0:
; ATOM-NEXT: #APP ; ATOM-NEXT: #APP
; ATOM-NEXT: fcmovb %st(1), %st(0) ; ATOM-NEXT: fcmovb %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovbe %st(1), %st(0) ; ATOM-NEXT: fcmovbe %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmove %st(1), %st(0) ; ATOM-NEXT: fcmove %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovnb %st(1), %st(0) ; ATOM-NEXT: fcmovnb %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovnbe %st(1), %st(0) ; ATOM-NEXT: fcmovnbe %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovne %st(1), %st(0) ; ATOM-NEXT: fcmovne %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovnu %st(1), %st(0) ; ATOM-NEXT: fcmovnu %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: fcmovu %st(1), %st(0) ; ATOM-NEXT: fcmovu %st(1), %st(0) # sched: [9:4.50]
; ATOM-NEXT: #NO_APP ; ATOM-NEXT: #NO_APP
; ATOM-NEXT: retl # sched: [79:39.50] ; ATOM-NEXT: retl # sched: [79:39.50]
; ;
; SLM-LABEL: test_fcmov: ; SLM-LABEL: test_fcmov:
; SLM: # %bb.0: ; SLM: # %bb.0:
; SLM-NEXT: #APP ; SLM-NEXT: #APP
; SLM-NEXT: fcmovb %st(1), %st(0) ; SLM-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovbe %st(1), %st(0) ; SLM-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmove %st(1), %st(0) ; SLM-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovnb %st(1), %st(0) ; SLM-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovnbe %st(1), %st(0) ; SLM-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovne %st(1), %st(0) ; SLM-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovnu %st(1), %st(0) ; SLM-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: fcmovu %st(1), %st(0) ; SLM-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; SLM-NEXT: #NO_APP ; SLM-NEXT: #NO_APP
; SLM-NEXT: retl # sched: [4:1.00] ; SLM-NEXT: retl # sched: [4:1.00]
; ;
@ -638,70 +638,70 @@ define void @test_fcmov() optsize {
; HASWELL-LABEL: test_fcmov: ; HASWELL-LABEL: test_fcmov:
; HASWELL: # %bb.0: ; HASWELL: # %bb.0:
; HASWELL-NEXT: #APP ; HASWELL-NEXT: #APP
; HASWELL-NEXT: fcmovb %st(1), %st(0) ; HASWELL-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovbe %st(1), %st(0) ; HASWELL-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmove %st(1), %st(0) ; HASWELL-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovnb %st(1), %st(0) ; HASWELL-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovnbe %st(1), %st(0) ; HASWELL-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovne %st(1), %st(0) ; HASWELL-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovnu %st(1), %st(0) ; HASWELL-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: fcmovu %st(1), %st(0) ; HASWELL-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; HASWELL-NEXT: #NO_APP ; HASWELL-NEXT: #NO_APP
; HASWELL-NEXT: retl # sched: [5:0.50] ; HASWELL-NEXT: retl # sched: [5:0.50]
; ;
; BROADWELL-LABEL: test_fcmov: ; BROADWELL-LABEL: test_fcmov:
; BROADWELL: # %bb.0: ; BROADWELL: # %bb.0:
; BROADWELL-NEXT: #APP ; BROADWELL-NEXT: #APP
; BROADWELL-NEXT: fcmovb %st(1), %st(0) ; BROADWELL-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovbe %st(1), %st(0) ; BROADWELL-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmove %st(1), %st(0) ; BROADWELL-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovnb %st(1), %st(0) ; BROADWELL-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovnbe %st(1), %st(0) ; BROADWELL-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovne %st(1), %st(0) ; BROADWELL-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovnu %st(1), %st(0) ; BROADWELL-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: fcmovu %st(1), %st(0) ; BROADWELL-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; BROADWELL-NEXT: #NO_APP ; BROADWELL-NEXT: #NO_APP
; BROADWELL-NEXT: retl # sched: [6:0.50] ; BROADWELL-NEXT: retl # sched: [6:0.50]
; ;
; SKYLAKE-LABEL: test_fcmov: ; SKYLAKE-LABEL: test_fcmov:
; SKYLAKE: # %bb.0: ; SKYLAKE: # %bb.0:
; SKYLAKE-NEXT: #APP ; SKYLAKE-NEXT: #APP
; SKYLAKE-NEXT: fcmovb %st(1), %st(0) ; SKYLAKE-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovbe %st(1), %st(0) ; SKYLAKE-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmove %st(1), %st(0) ; SKYLAKE-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovnb %st(1), %st(0) ; SKYLAKE-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovnbe %st(1), %st(0) ; SKYLAKE-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovne %st(1), %st(0) ; SKYLAKE-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovnu %st(1), %st(0) ; SKYLAKE-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: fcmovu %st(1), %st(0) ; SKYLAKE-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; SKYLAKE-NEXT: #NO_APP ; SKYLAKE-NEXT: #NO_APP
; SKYLAKE-NEXT: retl # sched: [6:0.50] ; SKYLAKE-NEXT: retl # sched: [6:0.50]
; ;
; SKX-LABEL: test_fcmov: ; SKX-LABEL: test_fcmov:
; SKX: # %bb.0: ; SKX: # %bb.0:
; SKX-NEXT: #APP ; SKX-NEXT: #APP
; SKX-NEXT: fcmovb %st(1), %st(0) ; SKX-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovbe %st(1), %st(0) ; SKX-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmove %st(1), %st(0) ; SKX-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovnb %st(1), %st(0) ; SKX-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovnbe %st(1), %st(0) ; SKX-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovne %st(1), %st(0) ; SKX-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovnu %st(1), %st(0) ; SKX-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: fcmovu %st(1), %st(0) ; SKX-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; SKX-NEXT: #NO_APP ; SKX-NEXT: #NO_APP
; SKX-NEXT: retl # sched: [6:0.50] ; SKX-NEXT: retl # sched: [6:0.50]
; ;
; BTVER2-LABEL: test_fcmov: ; BTVER2-LABEL: test_fcmov:
; BTVER2: # %bb.0: ; BTVER2: # %bb.0:
; BTVER2-NEXT: #APP ; BTVER2-NEXT: #APP
; BTVER2-NEXT: fcmovb %st(1), %st(0) ; BTVER2-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovbe %st(1), %st(0) ; BTVER2-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmove %st(1), %st(0) ; BTVER2-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovnb %st(1), %st(0) ; BTVER2-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovnbe %st(1), %st(0) ; BTVER2-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovne %st(1), %st(0) ; BTVER2-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovnu %st(1), %st(0) ; BTVER2-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: fcmovu %st(1), %st(0) ; BTVER2-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00]
; BTVER2-NEXT: #NO_APP ; BTVER2-NEXT: #NO_APP
; BTVER2-NEXT: retl # sched: [4:1.00] ; BTVER2-NEXT: retl # sched: [4:1.00]
; ;
@ -710,7 +710,7 @@ define void @test_fcmov() optsize {
; ZNVER1-NEXT: #APP ; ZNVER1-NEXT: #APP
; ZNVER1-NEXT: fcmovb %st(1), %st(0) # sched: [100:?] ; ZNVER1-NEXT: fcmovb %st(1), %st(0) # sched: [100:?]
; ZNVER1-NEXT: fcmovbe %st(1), %st(0) # sched: [100:?] ; ZNVER1-NEXT: fcmovbe %st(1), %st(0) # sched: [100:?]
; ZNVER1-NEXT: fcmove %st(1), %st(0) ; ZNVER1-NEXT: fcmove %st(1), %st(0) # sched: [100:?]
; ZNVER1-NEXT: fcmovnb %st(1), %st(0) # sched: [100:?] ; ZNVER1-NEXT: fcmovnb %st(1), %st(0) # sched: [100:?]
; ZNVER1-NEXT: fcmovnbe %st(1), %st(0) # sched: [100:?] ; ZNVER1-NEXT: fcmovnbe %st(1), %st(0) # sched: [100:?]
; ZNVER1-NEXT: fcmovne %st(1), %st(0) # sched: [100:?] ; ZNVER1-NEXT: fcmovne %st(1), %st(0) # sched: [100:?]