Skip to content

Commit 5c68c6d

Browse files
authored
[X86] Support encoding/decoding and lowering for APX variant SHL/SHR/SAR/ROL/ROR/RCL/RCR/SHLD/SHRD (#78853)
Four variants: promoted legacy, ND (new data destination), NF (no flags update) and NF_ND (NF + ND). The syntax of NF instructions is aligned with GNU binutils. https://sourceware.org/pipermail/binutils/2023-September/129545.html
1 parent bffd80d commit 5c68c6d

38 files changed

+10877
-122
lines changed

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 90 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,24 +1789,47 @@ let Predicates = [HasNDD] in {
17891789
// Shift amount is implicitly masked.
17901790
multiclass MaskedShiftAmountPats<SDNode frag> {
17911791
// (shift x (and y, 31)) ==> (shift x, y)
1792-
def : Pat<(frag GR8:$src1, (shiftMask32 CL)),
1793-
(!cast<Instruction>(NAME # "8rCL") GR8:$src1)>;
1794-
def : Pat<(frag GR16:$src1, (shiftMask32 CL)),
1795-
(!cast<Instruction>(NAME # "16rCL") GR16:$src1)>;
1796-
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1797-
(!cast<Instruction>(NAME # "32rCL") GR32:$src1)>;
1792+
// (shift x (and y, 63)) ==> (shift x, y)
1793+
let Predicates = [NoNDD] in {
1794+
def : Pat<(frag GR8:$src1, (shiftMask32 CL)),
1795+
(!cast<Instruction>(NAME # "8rCL") GR8:$src1)>;
1796+
def : Pat<(frag GR16:$src1, (shiftMask32 CL)),
1797+
(!cast<Instruction>(NAME # "16rCL") GR16:$src1)>;
1798+
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1799+
(!cast<Instruction>(NAME # "32rCL") GR32:$src1)>;
1800+
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1801+
(!cast<Instruction>(NAME # "64rCL") GR64:$src1)>;
1802+
}
1803+
let Predicates = [HasNDD] in {
1804+
def : Pat<(frag GR8:$src1, (shiftMask32 CL)),
1805+
(!cast<Instruction>(NAME # "8rCL_ND") GR8:$src1)>;
1806+
def : Pat<(frag GR16:$src1, (shiftMask32 CL)),
1807+
(!cast<Instruction>(NAME # "16rCL_ND") GR16:$src1)>;
1808+
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1809+
(!cast<Instruction>(NAME # "32rCL_ND") GR32:$src1)>;
1810+
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1811+
(!cast<Instruction>(NAME # "64rCL_ND") GR64:$src1)>;
1812+
}
1813+
17981814
def : Pat<(store (frag (loadi8 addr:$dst), (shiftMask32 CL)), addr:$dst),
17991815
(!cast<Instruction>(NAME # "8mCL") addr:$dst)>;
18001816
def : Pat<(store (frag (loadi16 addr:$dst), (shiftMask32 CL)), addr:$dst),
18011817
(!cast<Instruction>(NAME # "16mCL") addr:$dst)>;
18021818
def : Pat<(store (frag (loadi32 addr:$dst), (shiftMask32 CL)), addr:$dst),
18031819
(!cast<Instruction>(NAME # "32mCL") addr:$dst)>;
1804-
1805-
// (shift x (and y, 63)) ==> (shift x, y)
1806-
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1807-
(!cast<Instruction>(NAME # "64rCL") GR64:$src1)>;
18081820
def : Pat<(store (frag (loadi64 addr:$dst), (shiftMask64 CL)), addr:$dst),
18091821
(!cast<Instruction>(NAME # "64mCL") addr:$dst)>;
1822+
1823+
let Predicates = [HasNDD] in {
1824+
def : Pat<(frag (loadi8 addr:$src), (shiftMask32 CL)),
1825+
(!cast<Instruction>(NAME # "8mCL_ND") addr:$src)>;
1826+
def : Pat<(frag (loadi16 addr:$src), (shiftMask32 CL)),
1827+
(!cast<Instruction>(NAME # "16mCL_ND") addr:$src)>;
1828+
def : Pat<(frag (loadi32 addr:$src), (shiftMask32 CL)),
1829+
(!cast<Instruction>(NAME # "32mCL_ND") addr:$src)>;
1830+
def : Pat<(frag (loadi64 addr:$src), (shiftMask64 CL)),
1831+
(!cast<Instruction>(NAME # "64mCL_ND") addr:$src)>;
1832+
}
18101833
}
18111834

18121835
defm SHL : MaskedShiftAmountPats<shl>;
@@ -1821,47 +1844,76 @@ defm SAR : MaskedShiftAmountPats<sra>;
18211844
// not tracking flags for these nodes.
18221845
multiclass MaskedRotateAmountPats<SDNode frag> {
18231846
// (rot x (and y, BitWidth - 1)) ==> (rot x, y)
1824-
def : Pat<(frag GR8:$src1, (shiftMask8 CL)),
1825-
(!cast<Instruction>(NAME # "8rCL") GR8:$src1)>;
1826-
def : Pat<(frag GR16:$src1, (shiftMask16 CL)),
1827-
(!cast<Instruction>(NAME # "16rCL") GR16:$src1)>;
1828-
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1829-
(!cast<Instruction>(NAME # "32rCL") GR32:$src1)>;
1847+
let Predicates = [NoNDD] in {
1848+
def : Pat<(frag GR8:$src1, (shiftMask8 CL)),
1849+
(!cast<Instruction>(NAME # "8rCL") GR8:$src1)>;
1850+
def : Pat<(frag GR16:$src1, (shiftMask16 CL)),
1851+
(!cast<Instruction>(NAME # "16rCL") GR16:$src1)>;
1852+
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1853+
(!cast<Instruction>(NAME # "32rCL") GR32:$src1)>;
1854+
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1855+
(!cast<Instruction>(NAME # "64rCL") GR64:$src1)>;
1856+
}
1857+
let Predicates = [HasNDD] in {
1858+
def : Pat<(frag GR8:$src1, (shiftMask8 CL)),
1859+
(!cast<Instruction>(NAME # "8rCL_ND") GR8:$src1)>;
1860+
def : Pat<(frag GR16:$src1, (shiftMask16 CL)),
1861+
(!cast<Instruction>(NAME # "16rCL_ND") GR16:$src1)>;
1862+
def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1863+
(!cast<Instruction>(NAME # "32rCL_ND") GR32:$src1)>;
1864+
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1865+
(!cast<Instruction>(NAME # "64rCL_ND") GR64:$src1)>;
1866+
}
1867+
18301868
def : Pat<(store (frag (loadi8 addr:$dst), (shiftMask8 CL)), addr:$dst),
18311869
(!cast<Instruction>(NAME # "8mCL") addr:$dst)>;
18321870
def : Pat<(store (frag (loadi16 addr:$dst), (shiftMask16 CL)), addr:$dst),
18331871
(!cast<Instruction>(NAME # "16mCL") addr:$dst)>;
18341872
def : Pat<(store (frag (loadi32 addr:$dst), (shiftMask32 CL)), addr:$dst),
18351873
(!cast<Instruction>(NAME # "32mCL") addr:$dst)>;
1836-
1837-
// (rot x (and y, 63)) ==> (rot x, y)
1838-
def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1839-
(!cast<Instruction>(NAME # "64rCL") GR64:$src1)>;
18401874
def : Pat<(store (frag (loadi64 addr:$dst), (shiftMask64 CL)), addr:$dst),
18411875
(!cast<Instruction>(NAME # "64mCL") addr:$dst)>;
1876+
1877+
let Predicates = [HasNDD] in {
1878+
def : Pat<(frag (loadi8 addr:$src), (shiftMask8 CL)),
1879+
(!cast<Instruction>(NAME # "8mCL_ND") addr:$src)>;
1880+
def : Pat<(frag (loadi16 addr:$src), (shiftMask16 CL)),
1881+
(!cast<Instruction>(NAME # "16mCL_ND") addr:$src)>;
1882+
def : Pat<(frag (loadi32 addr:$src), (shiftMask32 CL)),
1883+
(!cast<Instruction>(NAME # "32mCL_ND") addr:$src)>;
1884+
def : Pat<(frag (loadi64 addr:$src), (shiftMask64 CL)),
1885+
(!cast<Instruction>(NAME # "64mCL_ND") addr:$src)>;
1886+
}
18421887
}
18431888

18441889
defm ROL : MaskedRotateAmountPats<rotl>;
18451890
defm ROR : MaskedRotateAmountPats<rotr>;
18461891

1847-
// Double "funnel" shift amount is implicitly masked.
1848-
// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y) (NOTE: modulo32)
1849-
def : Pat<(X86fshl GR16:$src1, GR16:$src2, (shiftMask32 CL)),
1850-
(SHLD16rrCL GR16:$src1, GR16:$src2)>;
1851-
def : Pat<(X86fshr GR16:$src2, GR16:$src1, (shiftMask32 CL)),
1852-
(SHRD16rrCL GR16:$src1, GR16:$src2)>;
1853-
1854-
// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y)
1855-
def : Pat<(fshl GR32:$src1, GR32:$src2, (shiftMask32 CL)),
1856-
(SHLD32rrCL GR32:$src1, GR32:$src2)>;
1857-
def : Pat<(fshr GR32:$src2, GR32:$src1, (shiftMask32 CL)),
1858-
(SHRD32rrCL GR32:$src1, GR32:$src2)>;
1859-
1860-
// (fshl/fshr x (and y, 63)) ==> (fshl/fshr x, y)
1861-
def : Pat<(fshl GR64:$src1, GR64:$src2, (shiftMask64 CL)),
1862-
(SHLD64rrCL GR64:$src1, GR64:$src2)>;
1863-
def : Pat<(fshr GR64:$src2, GR64:$src1, (shiftMask64 CL)),
1864-
(SHRD64rrCL GR64:$src1, GR64:$src2)>;
1892+
multiclass MaskedShlrdAmountPats<string suffix, Predicate p> {
1893+
let Predicates = [p] in {
1894+
// Double "funnel" shift amount is implicitly masked.
1895+
// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y) (NOTE: modulo32)
1896+
def : Pat<(X86fshl GR16:$src1, GR16:$src2, (shiftMask32 CL)),
1897+
(!cast<Instruction>(SHLD16rrCL#suffix) GR16:$src1, GR16:$src2)>;
1898+
def : Pat<(X86fshr GR16:$src2, GR16:$src1, (shiftMask32 CL)),
1899+
(!cast<Instruction>(SHRD16rrCL#suffix) GR16:$src1, GR16:$src2)>;
1900+
1901+
// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y)
1902+
def : Pat<(fshl GR32:$src1, GR32:$src2, (shiftMask32 CL)),
1903+
(!cast<Instruction>(SHLD32rrCL#suffix) GR32:$src1, GR32:$src2)>;
1904+
def : Pat<(fshr GR32:$src2, GR32:$src1, (shiftMask32 CL)),
1905+
(!cast<Instruction>(SHRD32rrCL#suffix) GR32:$src1, GR32:$src2)>;
1906+
1907+
// (fshl/fshr x (and y, 63)) ==> (fshl/fshr x, y)
1908+
def : Pat<(fshl GR64:$src1, GR64:$src2, (shiftMask64 CL)),
1909+
(!cast<Instruction>(SHLD64rrCL#suffix) GR64:$src1, GR64:$src2)>;
1910+
def : Pat<(fshr GR64:$src2, GR64:$src1, (shiftMask64 CL)),
1911+
(!cast<Instruction>(SHRD64rrCL#suffix) GR64:$src1, GR64:$src2)>;
1912+
}
1913+
}
1914+
1915+
defm : MaskedShlrdAmountPats<"", NoNDD>;
1916+
defm : MaskedShlrdAmountPats<"_ND", HasNDD>;
18651917

18661918
// Use BTR/BTS/BTC for clearing/setting/toggling a bit in a variable location.
18671919
multiclass OneBitPats<RegisterClass rc, ValueType vt, Instruction btr,

0 commit comments

Comments
 (0)