Index: lib/Target/X86/X86InstrMMX.td =================================================================== --- lib/Target/X86/X86InstrMMX.td +++ lib/Target/X86/X86InstrMMX.td @@ -635,7 +635,7 @@ "pmovmskb\t{$src, $dst|$dst, $src}", [(set GR32orGR64:$dst, (int_x86_mmx_pmovmskb VR64:$src))], - IIC_MMX_MOVMSK>, Sched<[WriteVecLogic]>; + IIC_MMX_MOVMSK>, Sched<[WriteVecMOVMSK]>; // Low word of XMM to MMX. def MMX_X86movdq2q : SDNode<"X86ISD::MOVDQ2Q", SDTypeProfile<1, 1, Index: lib/Target/X86/X86InstrSSE.td =================================================================== --- lib/Target/X86/X86InstrSSE.td +++ lib/Target/X86/X86InstrSSE.td @@ -2593,7 +2593,7 @@ def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src), !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [(set GR32orGR64:$dst, (X86movmsk (vt RC:$src)))], IIC_SSE_MOVMSK, d>, - Sched<[WriteVecLogic]>; + Sched<[WriteFMOVMSK]>; } let Predicates = [HasAVX] in { @@ -4271,7 +4271,7 @@ // SSE2 - Packed Mask Creation //===---------------------------------------------------------------------===// -let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in { +let ExeDomain = SSEPackedInt, SchedRW = [WriteVecMOVMSK] in { def VPMOVMSKBrr : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src), @@ -4283,8 +4283,8 @@ def VPMOVMSKBYrr : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR256:$src), "pmovmskb\t{$src, $dst|$dst, $src}", - [(set GR32orGR64:$dst, (X86movmsk (v32i8 VR256:$src)))]>, - VEX, VEX_L, VEX_WIG; + [(set GR32orGR64:$dst, (X86movmsk (v32i8 VR256:$src)))], + IIC_SSE_MOVMSK>, VEX, VEX_L, VEX_WIG; } def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src), Index: lib/Target/X86/X86SchedBroadwell.td =================================================================== --- lib/Target/X86/X86SchedBroadwell.td +++ lib/Target/X86/X86SchedBroadwell.td @@ -227,6 +227,10 @@ let ResourceCycles = [4,3,1,1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 3; } +def : WriteRes { let Latency = 3; } + // AES instructions. def : WriteRes { // Decryption, encryption. let Latency = 7; @@ -297,7 +301,6 @@ } def: InstRW<[BWWriteResGroup1], (instregex "MMX_MOVD64from64rr", "MMX_MOVD64grr", - "MMX_PMOVMSKBrr", "MMX_PSLLDri", "MMX_PSLLDrr", "MMX_PSLLQri", @@ -839,15 +842,6 @@ "STOSQ", "STOSW")>; -def BWWriteResGroup26 : SchedWriteRes<[BWPort0]> { - let Latency = 3; - let NumMicroOps = 1; - let ResourceCycles = [1]; -} -def: InstRW<[BWWriteResGroup26], (instregex "(V?)MOVMSKPD(Y?)rr", - "(V?)MOVMSKPS(Y?)rr", - "(V?)PMOVMSKB(Y?)rr")>; - def BWWriteResGroup27 : SchedWriteRes<[BWPort1]> { let Latency = 3; let NumMicroOps = 1; Index: lib/Target/X86/X86SchedHaswell.td =================================================================== --- lib/Target/X86/X86SchedHaswell.td +++ lib/Target/X86/X86SchedHaswell.td @@ -216,6 +216,10 @@ let ResourceCycles = [4,3,1,1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 3; } +def : WriteRes { let Latency = 3; } + // AES Instructions. def : WriteRes { let Latency = 7; @@ -658,7 +662,6 @@ } def: InstRW<[HWWriteResGroup2], (instregex "MMX_MOVD64from64rr", "MMX_MOVD64grr", - "MMX_PMOVMSKBrr", "MMX_PSLLDri", "MMX_PSLLDrr", "MMX_PSLLQri", @@ -1763,15 +1766,6 @@ def: InstRW<[HWWriteResGroup48], (instregex "CALL(16|32|64)m", "FARCALL64")>; -def HWWriteResGroup49 : SchedWriteRes<[HWPort0]> { - let Latency = 3; - let NumMicroOps = 1; - let ResourceCycles = [1]; -} -def: InstRW<[HWWriteResGroup49], (instregex "(V?)MOVMSKPD(Y?)rr", - "(V?)MOVMSKPS(Y?)rr", - "(V?)PMOVMSKB(Y?)rr")>; - def HWWriteResGroup50 : SchedWriteRes<[HWPort1]> { let Latency = 3; let NumMicroOps = 1; Index: lib/Target/X86/X86SchedSandyBridge.td =================================================================== --- lib/Target/X86/X86SchedSandyBridge.td +++ lib/Target/X86/X86SchedSandyBridge.td @@ -204,6 +204,10 @@ let ResourceCycles = [7, 1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 2; } +def : WriteRes { let Latency = 2; } + // AES Instructions. def : WriteRes { let Latency = 7; @@ -527,10 +531,7 @@ let NumMicroOps = 1; let ResourceCycles = [1]; } -def: InstRW<[SBWriteResGroup7], (instregex "(V?)PMOVMSKBrr", - "(V?)MOVMSKPD(Y?)rr", - "(V?)MOVMSKPS(Y?)rr", - "(V?)MOVPDI2DIrr", +def: InstRW<[SBWriteResGroup7], (instregex "(V?)MOVPDI2DIrr", "(V?)MOVPQIto64rr")>; def SBWriteResGroup9 : SchedWriteRes<[SBPort05]> { Index: lib/Target/X86/X86SchedSkylakeClient.td =================================================================== --- lib/Target/X86/X86SchedSkylakeClient.td +++ lib/Target/X86/X86SchedSkylakeClient.td @@ -224,6 +224,10 @@ let ResourceCycles = [4,3,1,1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 2; } +def : WriteRes { let Latency = 2; } + // AES instructions. def : WriteRes { // Decryption, encryption. let Latency = 4; @@ -692,14 +696,10 @@ } def: InstRW<[SKLWriteResGroup12], (instregex "MMX_MOVD64from64rr", "MMX_MOVD64grr", - "MMX_PMOVMSKBrr", "(V?)COMISDrr", "(V?)COMISSrr", - "(V?)MOVMSKPD(Y?)rr", - "(V?)MOVMSKPS(Y?)rr", "(V?)MOVPDI2DIrr", "(V?)MOVPQIto64rr", - "(V?)PMOVMSKB(Y?)rr", "VTESTPD(Y?)rr", "VTESTPS(Y?)rr", "(V?)UCOMISDrr", Index: lib/Target/X86/X86SchedSkylakeServer.td =================================================================== --- lib/Target/X86/X86SchedSkylakeServer.td +++ lib/Target/X86/X86SchedSkylakeServer.td @@ -224,6 +224,10 @@ let ResourceCycles = [4,3,1,1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 2; } +def : WriteRes { let Latency = 2; } + // AES instructions. def : WriteRes { // Decryption, encryption. let Latency = 4; @@ -1444,28 +1448,18 @@ "COMISSrr", "MMX_MOVD64from64rr", "MMX_MOVD64grr", - "MMX_PMOVMSKBrr", - "MOVMSKPDrr", - "MOVMSKPSrr", "MOVPDI2DIrr", "MOVPQIto64rr", - "PMOVMSKBrr", "UCOMISDrr", "UCOMISSrr", "VCOMISDZrr(b?)", "VCOMISDrr", "VCOMISSZrr(b?)", "VCOMISSrr", - "VMOVMSKPDYrr", - "VMOVMSKPDrr", - "VMOVMSKPSYrr", - "VMOVMSKPSrr", "VMOVPDI2DIZrr(b?)(k?)(z?)", "VMOVPDI2DIrr", "VMOVPQIto64Zrr(b?)(k?)(z?)", "VMOVPQIto64rr", - "VPMOVMSKBYrr", - "VPMOVMSKBrr", "VTESTPDYrr", "VTESTPDrr", "VTESTPSYrr", Index: lib/Target/X86/X86Schedule.td =================================================================== --- lib/Target/X86/X86Schedule.td +++ lib/Target/X86/X86Schedule.td @@ -105,6 +105,10 @@ // These are often used on both floating point and integer vectors. defm WriteVecLogic : X86SchedWritePair; // Vector and/or/xor. +// MOVMSK operations. +def WriteFMOVMSK : SchedWrite; +def WriteVecMOVMSK : SchedWrite; + // Conversion between integer and float. defm WriteCvtF2I : X86SchedWritePair; // Float -> Integer. defm WriteCvtI2F : X86SchedWritePair; // Integer -> Float. Index: lib/Target/X86/X86ScheduleBtVer2.td =================================================================== --- lib/Target/X86/X86ScheduleBtVer2.td +++ lib/Target/X86/X86ScheduleBtVer2.td @@ -359,6 +359,13 @@ defm : JWriteResFpuPair; //////////////////////////////////////////////////////////////////////////////// +// MOVMSK Instructions. +//////////////////////////////////////////////////////////////////////////////// + +def : WriteRes { let Latency = 3; } +def : WriteRes { let Latency = 3; } + +//////////////////////////////////////////////////////////////////////////////// // AES Instructions. //////////////////////////////////////////////////////////////////////////////// @@ -771,13 +778,6 @@ } def : InstRW<[JWriteVMaskMovYSt], (instrs VMASKMOVPDYmr, VMASKMOVPSYmr)>; -def JWriteVMOVMSK: SchedWriteRes<[JFPU0, JFPA, JALU0]> { - let Latency = 3; -} -def : InstRW<[JWriteVMOVMSK], (instrs MOVMSKPDrr, VMOVMSKPDrr, VMOVMSKPDYrr, - MOVMSKPSrr, VMOVMSKPSrr, VMOVMSKPSYrr, - PMOVMSKBrr, VPMOVMSKBrr, MMX_PMOVMSKBrr)>; - def JWriteVTESTY: SchedWriteRes<[JFPU01, JFPX, JFPA, JALU0]> { let Latency = 4; let ResourceCycles = [2, 2, 2, 1]; Index: lib/Target/X86/X86ScheduleSLM.td =================================================================== --- lib/Target/X86/X86ScheduleSLM.td +++ lib/Target/X86/X86ScheduleSLM.td @@ -185,6 +185,10 @@ let ResourceCycles = [21, 1]; } +// MOVMSK Instructions. +def : WriteRes { let Latency = 4; } +def : WriteRes { let Latency = 4; } + // AES Instructions. def : WriteRes { let Latency = 8; Index: lib/Target/X86/X86ScheduleZnver1.td =================================================================== --- lib/Target/X86/X86ScheduleZnver1.td +++ lib/Target/X86/X86ScheduleZnver1.td @@ -216,6 +216,10 @@ // Vector Shift Operations defm : ZnWriteResFpuPair; +// MOVMSK Instructions. +def : WriteRes; +def : WriteRes; + // AES Instructions. defm : ZnWriteResFpuPair; defm : ZnWriteResFpuPair; @@ -1004,14 +1008,12 @@ // m, v,v. def : InstRW<[WriteMicrocoded], (instregex "VPMASKMOV(D|Q)(Y?)mr")>; -// PMOVMSKB. -def ZnWritePMOVMSKB : SchedWriteRes<[ZnFPU2]> { - let NumMicroOps = 2; -} +// PMOVMSKBY. def ZnWritePMOVMSKBY : SchedWriteRes<[ZnFPU2]> { + let NumMicroOps = 2; let Latency = 2; + let ResourceCycles = [2]; } -def : InstRW<[ZnWritePMOVMSKB], (instregex "(V|MMX_)?PMOVMSKBrr")>; def : InstRW<[ZnWritePMOVMSKBY], (instregex "(V|MMX_)?PMOVMSKBYrr")>; // PEXTR B/W/D/Q. @@ -1150,11 +1152,6 @@ //=== Floating Point XMM and YMM Instructions ===// //-- Move instructions --// -// MOVMSKP S/D. -// r32 <- x,y. -def ZnWriteMOVMSKPr : SchedWriteRes<[ZnFPU2]> ; -def : InstRW<[ZnWriteMOVMSKPr], (instregex "(V?)MOVMSKP(S|D)(Y?)rr")>; - // VPERM2F128. def : InstRW<[WriteMicrocoded], (instregex "VPERM2F128rr")>; def : InstRW<[WriteMicrocoded], (instregex "VPERM2F128rm")>; Index: test/CodeGen/X86/avx2-schedule.ll =================================================================== --- test/CodeGen/X86/avx2-schedule.ll +++ test/CodeGen/X86/avx2-schedule.ll @@ -4096,7 +4096,7 @@ define i32 @test_pmovmskb(<32 x i8> %a0) { ; GENERIC-LABEL: test_pmovmskb: ; GENERIC: # %bb.0: -; GENERIC-NEXT: vpmovmskb %ymm0, %eax # sched: [1:1.00] +; GENERIC-NEXT: vpmovmskb %ymm0, %eax # sched: [2:1.00] ; GENERIC-NEXT: vzeroupper # sched: [100:0.33] ; GENERIC-NEXT: retq # sched: [1:1.00] ; @@ -4126,7 +4126,7 @@ ; ; ZNVER1-LABEL: test_pmovmskb: ; ZNVER1: # %bb.0: -; ZNVER1-NEXT: vpmovmskb %ymm0, %eax # sched: [2:1.00] +; ZNVER1-NEXT: vpmovmskb %ymm0, %eax # sched: [2:2.00] ; ZNVER1-NEXT: vzeroupper # sched: [100:?] ; ZNVER1-NEXT: retq # sched: [1:0.50] %1 = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> %a0) Index: test/CodeGen/X86/mmx-schedule.ll =================================================================== --- test/CodeGen/X86/mmx-schedule.ll +++ test/CodeGen/X86/mmx-schedule.ll @@ -4058,7 +4058,7 @@ define i32 @test_pmovmskb(x86_mmx %a0) optsize { ; GENERIC-LABEL: test_pmovmskb: ; GENERIC: # %bb.0: -; GENERIC-NEXT: pmovmskb %mm0, %eax # sched: [1:1.00] +; GENERIC-NEXT: pmovmskb %mm0, %eax # sched: [2:1.00] ; GENERIC-NEXT: retq # sched: [1:1.00] ; ; ATOM-LABEL: test_pmovmskb: @@ -4068,22 +4068,22 @@ ; ; SLM-LABEL: test_pmovmskb: ; SLM: # %bb.0: -; SLM-NEXT: pmovmskb %mm0, %eax # sched: [1:0.50] +; SLM-NEXT: pmovmskb %mm0, %eax # sched: [4:1.00] ; SLM-NEXT: retq # sched: [4:1.00] ; ; SANDY-LABEL: test_pmovmskb: ; SANDY: # %bb.0: -; SANDY-NEXT: pmovmskb %mm0, %eax # sched: [1:1.00] +; SANDY-NEXT: pmovmskb %mm0, %eax # sched: [2:1.00] ; SANDY-NEXT: retq # sched: [1:1.00] ; ; HASWELL-LABEL: test_pmovmskb: ; HASWELL: # %bb.0: -; HASWELL-NEXT: pmovmskb %mm0, %eax # sched: [1:1.00] +; HASWELL-NEXT: pmovmskb %mm0, %eax # sched: [3:1.00] ; HASWELL-NEXT: retq # sched: [7:1.00] ; ; BROADWELL-LABEL: test_pmovmskb: ; BROADWELL: # %bb.0: -; BROADWELL-NEXT: pmovmskb %mm0, %eax # sched: [1:1.00] +; BROADWELL-NEXT: pmovmskb %mm0, %eax # sched: [3:1.00] ; BROADWELL-NEXT: retq # sched: [7:1.00] ; ; SKYLAKE-LABEL: test_pmovmskb: Index: test/CodeGen/X86/sse-schedule.ll =================================================================== --- test/CodeGen/X86/sse-schedule.ll +++ test/CodeGen/X86/sse-schedule.ll @@ -3098,7 +3098,7 @@ ; ; SLM-LABEL: test_movmskps: ; SLM: # %bb.0: -; SLM-NEXT: movmskps %xmm0, %eax # sched: [1:0.50] +; SLM-NEXT: movmskps %xmm0, %eax # sched: [4:1.00] ; SLM-NEXT: retq # sched: [4:1.00] ; ; SANDY-SSE-LABEL: test_movmskps: Index: test/CodeGen/X86/sse2-schedule.ll =================================================================== --- test/CodeGen/X86/sse2-schedule.ll +++ test/CodeGen/X86/sse2-schedule.ll @@ -5107,7 +5107,7 @@ ; ; SLM-LABEL: test_movmskpd: ; SLM: # %bb.0: -; SLM-NEXT: movmskpd %xmm0, %eax # sched: [1:0.50] +; SLM-NEXT: movmskpd %xmm0, %eax # sched: [4:1.00] ; SLM-NEXT: retq # sched: [4:1.00] ; ; SANDY-SSE-LABEL: test_movmskpd: @@ -9684,7 +9684,7 @@ ; ; SLM-LABEL: test_pmovmskb: ; SLM: # %bb.0: -; SLM-NEXT: pmovmskb %xmm0, %eax # sched: [1:0.50] +; SLM-NEXT: pmovmskb %xmm0, %eax # sched: [4:1.00] ; SLM-NEXT: retq # sched: [4:1.00] ; ; SANDY-SSE-LABEL: test_pmovmskb: