@@ -1789,24 +1789,47 @@ let Predicates = [HasNDD] in {
1789
1789
// Shift amount is implicitly masked.
1790
1790
multiclass MaskedShiftAmountPats<SDNode frag> {
1791
1791
// (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
+
1798
1814
def : Pat<(store (frag (loadi8 addr:$dst), (shiftMask32 CL)), addr:$dst),
1799
1815
(!cast<Instruction>(NAME # "8mCL") addr:$dst)>;
1800
1816
def : Pat<(store (frag (loadi16 addr:$dst), (shiftMask32 CL)), addr:$dst),
1801
1817
(!cast<Instruction>(NAME # "16mCL") addr:$dst)>;
1802
1818
def : Pat<(store (frag (loadi32 addr:$dst), (shiftMask32 CL)), addr:$dst),
1803
1819
(!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)>;
1808
1820
def : Pat<(store (frag (loadi64 addr:$dst), (shiftMask64 CL)), addr:$dst),
1809
1821
(!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
+ }
1810
1833
}
1811
1834
1812
1835
defm SHL : MaskedShiftAmountPats<shl>;
@@ -1821,47 +1844,77 @@ defm SAR : MaskedShiftAmountPats<sra>;
1821
1844
// not tracking flags for these nodes.
1822
1845
multiclass MaskedRotateAmountPats<SDNode frag> {
1823
1846
// (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
+ // (rot x (and y, 63)) ==> (rot x, y)
1848
+ let Predicates = [NoNDD] in {
1849
+ def : Pat<(frag GR8:$src1, (shiftMask8 CL)),
1850
+ (!cast<Instruction>(NAME # "8rCL") GR8:$src1)>;
1851
+ def : Pat<(frag GR16:$src1, (shiftMask16 CL)),
1852
+ (!cast<Instruction>(NAME # "16rCL") GR16:$src1)>;
1853
+ def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1854
+ (!cast<Instruction>(NAME # "32rCL") GR32:$src1)>;
1855
+ def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1856
+ (!cast<Instruction>(NAME # "64rCL") GR64:$src1)>;
1857
+ }
1858
+ let Predicates = [HasNDD] in {
1859
+ def : Pat<(frag GR8:$src1, (shiftMask8 CL)),
1860
+ (!cast<Instruction>(NAME # "8rCL_ND") GR8:$src1)>;
1861
+ def : Pat<(frag GR16:$src1, (shiftMask16 CL)),
1862
+ (!cast<Instruction>(NAME # "16rCL_ND") GR16:$src1)>;
1863
+ def : Pat<(frag GR32:$src1, (shiftMask32 CL)),
1864
+ (!cast<Instruction>(NAME # "32rCL_ND") GR32:$src1)>;
1865
+ def : Pat<(frag GR64:$src1, (shiftMask64 CL)),
1866
+ (!cast<Instruction>(NAME # "64rCL_ND") GR64:$src1)>;
1867
+ }
1868
+
1830
1869
def : Pat<(store (frag (loadi8 addr:$dst), (shiftMask8 CL)), addr:$dst),
1831
1870
(!cast<Instruction>(NAME # "8mCL") addr:$dst)>;
1832
1871
def : Pat<(store (frag (loadi16 addr:$dst), (shiftMask16 CL)), addr:$dst),
1833
1872
(!cast<Instruction>(NAME # "16mCL") addr:$dst)>;
1834
1873
def : Pat<(store (frag (loadi32 addr:$dst), (shiftMask32 CL)), addr:$dst),
1835
1874
(!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)>;
1840
1875
def : Pat<(store (frag (loadi64 addr:$dst), (shiftMask64 CL)), addr:$dst),
1841
1876
(!cast<Instruction>(NAME # "64mCL") addr:$dst)>;
1877
+
1878
+ let Predicates = [HasNDD] in {
1879
+ def : Pat<(frag (loadi8 addr:$src), (shiftMask8 CL)),
1880
+ (!cast<Instruction>(NAME # "8mCL_ND") addr:$src)>;
1881
+ def : Pat<(frag (loadi16 addr:$src), (shiftMask16 CL)),
1882
+ (!cast<Instruction>(NAME # "16mCL_ND") addr:$src)>;
1883
+ def : Pat<(frag (loadi32 addr:$src), (shiftMask32 CL)),
1884
+ (!cast<Instruction>(NAME # "32mCL_ND") addr:$src)>;
1885
+ def : Pat<(frag (loadi64 addr:$src), (shiftMask64 CL)),
1886
+ (!cast<Instruction>(NAME # "64mCL_ND") addr:$src)>;
1887
+ }
1842
1888
}
1843
1889
1844
1890
defm ROL : MaskedRotateAmountPats<rotl>;
1845
1891
defm ROR : MaskedRotateAmountPats<rotr>;
1846
1892
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)>;
1893
+ multiclass MaskedShlrdAmountPats<string suffix, Predicate p> {
1894
+ let Predicates = [p] in {
1895
+ // Double "funnel" shift amount is implicitly masked.
1896
+ // (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y) (NOTE: modulo32)
1897
+ def : Pat<(X86fshl GR16:$src1, GR16:$src2, (shiftMask32 CL)),
1898
+ (!cast<Instruction>(SHLD16rrCL#suffix) GR16:$src1, GR16:$src2)>;
1899
+ def : Pat<(X86fshr GR16:$src2, GR16:$src1, (shiftMask32 CL)),
1900
+ (!cast<Instruction>(SHRD16rrCL#suffix) GR16:$src1, GR16:$src2)>;
1901
+
1902
+ // (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y)
1903
+ def : Pat<(fshl GR32:$src1, GR32:$src2, (shiftMask32 CL)),
1904
+ (!cast<Instruction>(SHLD32rrCL#suffix) GR32:$src1, GR32:$src2)>;
1905
+ def : Pat<(fshr GR32:$src2, GR32:$src1, (shiftMask32 CL)),
1906
+ (!cast<Instruction>(SHRD32rrCL#suffix) GR32:$src1, GR32:$src2)>;
1907
+
1908
+ // (fshl/fshr x (and y, 63)) ==> (fshl/fshr x, y)
1909
+ def : Pat<(fshl GR64:$src1, GR64:$src2, (shiftMask64 CL)),
1910
+ (!cast<Instruction>(SHLD64rrCL#suffix) GR64:$src1, GR64:$src2)>;
1911
+ def : Pat<(fshr GR64:$src2, GR64:$src1, (shiftMask64 CL)),
1912
+ (!cast<Instruction>(SHRD64rrCL#suffix) GR64:$src1, GR64:$src2)>;
1913
+ }
1914
+ }
1915
+
1916
+ defm : MaskedShlrdAmountPats<"", NoNDD>;
1917
+ defm : MaskedShlrdAmountPats<"_ND", HasNDD>;
1865
1918
1866
1919
// Use BTR/BTS/BTC for clearing/setting/toggling a bit in a variable location.
1867
1920
multiclass OneBitPats<RegisterClass rc, ValueType vt, Instruction btr,
0 commit comments