@@ -1789,24 +1789,47 @@ let Predicates = [HasNDD] in {
17891789// Shift amount is implicitly masked.
17901790multiclass 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
18121835defm SHL : MaskedShiftAmountPats<shl>;
@@ -1821,47 +1844,76 @@ defm SAR : MaskedShiftAmountPats<sra>;
18211844// not tracking flags for these nodes.
18221845multiclass 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
18441889defm ROL : MaskedRotateAmountPats<rotl>;
18451890defm 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.
18671919multiclass OneBitPats<RegisterClass rc, ValueType vt, Instruction btr,
0 commit comments