From 4aabbc0c85b6c188d6cf9b45d548fbfb149dbc62 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 7 Nov 2022 12:27:02 +0000 Subject: [PATCH] [X86] Flatten WriteShift/Rotate SchedRW defs Some "inner" defs were being overriding "outer" SchedRW defs, making it very tricky to track what schedule was being used. Noticed as I'm trying to remove a lot of unnecessary shift/rotate RMW overrides from the scheduler models --- llvm/lib/Target/X86/X86InstrShiftRotate.td | 72 +++++++++++++++++------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/llvm/lib/Target/X86/X86InstrShiftRotate.td b/llvm/lib/Target/X86/X86InstrShiftRotate.td index 823ff78..e57169d 100644 --- a/llvm/lib/Target/X86/X86InstrShiftRotate.td +++ b/llvm/lib/Target/X86/X86InstrShiftRotate.td @@ -14,7 +14,7 @@ let Defs = [EFLAGS] in { -let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in { +let Constraints = "$src1 = $dst" in { let Uses = [CL], SchedRW = [WriteShiftCL] in { def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1), "shl{b}\t{%cl, $dst|$dst, cl}", @@ -30,6 +30,7 @@ def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src1), [(set GR64:$dst, (shl GR64:$src1, CL))]>; } // Uses = [CL], SchedRW +let SchedRW = [WriteShift] in { let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def SHL8ri : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), "shl{b}\t{$src2, $dst|$dst, $src2}", @@ -61,7 +62,8 @@ def SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1), def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1), "shl{q}\t$dst", []>; } // hasSideEffects = 0 -} // Constraints = "$src = $dst", SchedRW +} // SchedRW +} // Constraints = "$src = $dst" // FIXME: Why do we need an explicit "Uses = [CL]" when the instr has a pattern // using CL? @@ -81,7 +83,7 @@ def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst), "shl{q}\t{%cl, $dst|$dst, cl}", [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>, Requires<[In64BitMode]>; -} +} // Uses, SchedRW let SchedRW = [WriteShiftLd, WriteRMW] in { def SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, u8imm:$src), @@ -118,7 +120,7 @@ def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst), Requires<[In64BitMode]>; } // SchedRW -let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in { +let Constraints = "$src1 = $dst" in { let Uses = [CL], SchedRW = [WriteShiftCL] in { def SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src1), "shr{b}\t{%cl, $dst|$dst, cl}", @@ -132,8 +134,9 @@ def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src1), def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src1), "shr{q}\t{%cl, $dst|$dst, cl}", [(set GR64:$dst, (srl GR64:$src1, CL))]>; -} +} // Uses, SchedRW +let SchedRW = [WriteShift] in { def SHR8ri : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$src2), "shr{b}\t{$src2, $dst|$dst, $src2}", [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))]>; @@ -162,7 +165,8 @@ def SHR32r1 : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1), def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1), "shr{q}\t$dst", [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>; -} // Constraints = "$src = $dst", SchedRW +} // SchedRW +} // Constraints = "$src = $dst" let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in { @@ -181,7 +185,7 @@ def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst), "shr{q}\t{%cl, $dst|$dst, cl}", [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>, Requires<[In64BitMode]>; -} +} // Uses, SchedRW let SchedRW = [WriteShiftLd, WriteRMW] in { def SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, u8imm:$src), @@ -218,7 +222,7 @@ def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst), Requires<[In64BitMode]>; } // SchedRW -let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in { +let Constraints = "$src1 = $dst" in { let Uses = [CL], SchedRW = [WriteShiftCL] in { def SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1), "sar{b}\t{%cl, $dst|$dst, cl}", @@ -234,8 +238,9 @@ def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src1), def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src1), "sar{q}\t{%cl, $dst|$dst, cl}", [(set GR64:$dst, (sra GR64:$src1, CL))]>; -} +} // Uses, SchedRW +let SchedRW = [WriteShift] in { def SAR8ri : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), "sar{b}\t{$src2, $dst|$dst, $src2}", [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))]>; @@ -265,7 +270,8 @@ def SAR32r1 : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1), def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1), "sar{q}\t$dst", [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>; -} // Constraints = "$src = $dst", SchedRW +} // SchedRW +} // Constraints = "$src = $dst" let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in { @@ -284,7 +290,7 @@ def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst), "sar{q}\t{%cl, $dst|$dst, cl}", [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>, Requires<[In64BitMode]>; -} +} // Uses, SchedRW let SchedRW = [WriteShiftLd, WriteRMW] in { def SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, u8imm:$src), @@ -326,7 +332,7 @@ def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst), //===----------------------------------------------------------------------===// let hasSideEffects = 0 in { -let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in { +let Constraints = "$src1 = $dst" in { let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in { def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src1), @@ -337,9 +343,9 @@ def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src1), "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "rcl{q}\t{%cl, $dst|$dst, cl}", []>; -} // Uses = [CL, EFLAGS] +} // Uses = [CL, EFLAGS], SchedRW -let Uses = [EFLAGS] in { +let Uses = [EFLAGS], SchedRW = [WriteRotate] in { def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src1), "rcl{b}\t$dst", []>; def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt), @@ -356,7 +362,7 @@ def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "rcl{q}\t$dst", []>; def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt), "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>; -} // Uses = [EFLAGS] +} // Uses = [EFLAGS], SchedRW let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in { def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src1), @@ -367,9 +373,9 @@ def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src1), "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "rcr{q}\t{%cl, $dst|$dst, cl}", []>; -} // Uses = [CL, EFLAGS] +} // Uses = [CL, EFLAGS], SchedRW -let Uses = [EFLAGS] in { +let Uses = [EFLAGS], SchedRW = [WriteRotate] in { def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src1), "rcr{b}\t$dst", []>; def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt), @@ -386,12 +392,12 @@ def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "rcr{q}\t$dst", []>; def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt), "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>; -} // Uses = [EFLAGS] +} // Uses = [EFLAGS], SchedRW } // Constraints = "$src = $dst" -let SchedRW = [WriteRotateLd, WriteRMW], mayStore = 1 in { -let Uses = [EFLAGS] in { +let mayStore = 1 in { +let Uses = [EFLAGS], SchedRW = [WriteRotateLd, WriteRMW] in { def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst), "rcl{b}\t$dst", []>; def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, u8imm:$cnt), @@ -427,7 +433,7 @@ def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst), def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, u8imm:$cnt), "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>, Requires<[In64BitMode]>; -} // Uses = [EFLAGS] +} // Uses = [EFLAGS], SchedRW let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCLLd, WriteRMW] in { def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst), @@ -449,11 +455,11 @@ def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst), def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst), "rcr{q}\t{%cl, $dst|$dst, cl}", []>, Requires<[In64BitMode]>; -} // Uses = [CL, EFLAGS] -} // SchedRW +} // Uses = [CL, EFLAGS], SchedRW +} // mayStore } // hasSideEffects = 0 -let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in { +let Constraints = "$src1 = $dst" in { // FIXME: provide shorter instructions when imm8 == 1 let Uses = [CL], SchedRW = [WriteRotateCL] in { def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1), @@ -468,8 +474,9 @@ def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src1), def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "rol{q}\t{%cl, $dst|$dst, cl}", [(set GR64:$dst, (rotl GR64:$src1, CL))]>; -} +} // Uses, SchedRW +let SchedRW = [WriteRotate] in { def ROL8ri : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), "rol{b}\t{$src2, $dst|$dst, $src2}", [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))]>; @@ -499,7 +506,8 @@ def ROL32r1 : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1), def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "rol{q}\t$dst", [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>; -} // Constraints = "$src = $dst", SchedRW +} // SchedRW +} // Constraints = "$src = $dst" let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in { def ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst), @@ -515,7 +523,7 @@ def ROL64mCL : RI<0xD3, MRM0m, (outs), (ins i64mem:$dst), "rol{q}\t{%cl, $dst|$dst, cl}", [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>, Requires<[In64BitMode]>; -} +} // Uses, SchedRW let SchedRW = [WriteRotateLd, WriteRMW] in { def ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, u8imm:$src1), @@ -552,7 +560,7 @@ def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst), Requires<[In64BitMode]>; } // SchedRW -let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in { +let Constraints = "$src1 = $dst" in { let Uses = [CL], SchedRW = [WriteRotateCL] in { def ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1), "ror{b}\t{%cl, $dst|$dst, cl}", @@ -568,6 +576,7 @@ def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src1), [(set GR64:$dst, (rotr GR64:$src1, CL))]>; } +let SchedRW = [WriteRotate] in { def ROR8ri : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), "ror{b}\t{$src2, $dst|$dst, $src2}", [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))]>; @@ -597,6 +606,7 @@ def ROR32r1 : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1), def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "ror{q}\t$dst", [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>; +} // SchedRW } // Constraints = "$src = $dst", SchedRW let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in { @@ -613,7 +623,7 @@ def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), "ror{q}\t{%cl, $dst|$dst, cl}", [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>, Requires<[In64BitMode]>; -} +} // Uses, SchedRW let SchedRW = [WriteRotateLd, WriteRMW] in { def ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, u8imm:$src), @@ -688,7 +698,7 @@ def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", [(set GR64:$dst, (fshr GR64:$src2, GR64:$src1, CL))]>, TB; -} // SchedRW +} // Uses, SchedRW let isCommutable = 1, SchedRW = [WriteSHDrri] in { // These instructions commute to each other. def SHLD16rri8 : Ii8<0xA4, MRMDestReg, @@ -763,7 +773,7 @@ def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", [(store (fshr GR64:$src2, (loadi64 addr:$dst), CL), addr:$dst)]>, TB; -} // SchedRW +} // Uses, SchedRW let SchedRW = [WriteSHDmri] in { def SHLD16mri8 : Ii8<0xA4, MRMDestMem, -- 2.7.4