Skip to content

Commit d7fc770

Browse files
[LLVM][DAGCombiner] Improve simplifyDivRem's effectiveness after type legalisation. (llvm#162706)
simplifyDivRem does not work as well after type legalisation because splatted constants can have a size mismatch between the scalar to splat and the element type of the splatted result. simplifyDivRem does not seem to care about this mismatch so I've updated the "is one" check for the divisor to allow truncation.
1 parent 6712e20 commit d7fc770

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5044,7 +5044,6 @@ static SDValue simplifyDivRem(SDNode *N, SelectionDAG &DAG) {
50445044

50455045
unsigned Opc = N->getOpcode();
50465046
bool IsDiv = (ISD::SDIV == Opc) || (ISD::UDIV == Opc);
5047-
ConstantSDNode *N1C = isConstOrConstSplat(N1);
50485047

50495048
// X / undef -> undef
50505049
// X % undef -> undef
@@ -5076,7 +5075,7 @@ static SDValue simplifyDivRem(SDNode *N, SelectionDAG &DAG) {
50765075
// division-by-zero or remainder-by-zero, so assume the divisor is 1.
50775076
// TODO: Similarly, if we're zero-extending a boolean divisor, then assume
50785077
// it's a 1.
5079-
if ((N1C && N1C->isOne()) || (VT.getScalarType() == MVT::i1))
5078+
if (isOneOrOneSplat(N1) || (VT.getScalarType() == MVT::i1))
50805079
return IsDiv ? N0 : DAG.getConstant(0, DL, VT);
50815080

50825081
return SDValue();

llvm/test/CodeGen/AArch64/combine-sdiv.ll

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,3 +1774,88 @@ define i128 @combine_i128_sdiv_const100(i128 %x) {
17741774
%1 = sdiv i128 %x, 100
17751775
ret i128 %1
17761776
}
1777+
1778+
; The following only becomes an sdiv_by_one after type legalisation, after which
1779+
; the splatted scalar constant has a different type to the splat vector. This
1780+
; test verifies DAGCombiner does not care about this type difference.
1781+
define <16 x i16> @combine_vec_sdiv_by_one_obfuscated(<16 x i16> %x) "target-features"="+sve" {
1782+
; CHECK-SD-LABEL: combine_vec_sdiv_by_one_obfuscated:
1783+
; CHECK-SD: // %bb.0:
1784+
; CHECK-SD-NEXT: ret
1785+
;
1786+
; CHECK-GI-LABEL: combine_vec_sdiv_by_one_obfuscated:
1787+
; CHECK-GI: // %bb.0:
1788+
; CHECK-GI-NEXT: movi v2.2d, #0000000000000000
1789+
; CHECK-GI-NEXT: movi v3.8h, #1
1790+
; CHECK-GI-NEXT: smov w8, v0.h[0]
1791+
; CHECK-GI-NEXT: mov v3.h[0], v2.h[0]
1792+
; CHECK-GI-NEXT: smov w9, v3.h[0]
1793+
; CHECK-GI-NEXT: smov w16, v3.h[7]
1794+
; CHECK-GI-NEXT: sdiv w14, w8, w9
1795+
; CHECK-GI-NEXT: smov w8, v0.h[1]
1796+
; CHECK-GI-NEXT: smov w9, v3.h[1]
1797+
; CHECK-GI-NEXT: sdiv w15, w8, w9
1798+
; CHECK-GI-NEXT: smov w8, v0.h[2]
1799+
; CHECK-GI-NEXT: smov w9, v3.h[2]
1800+
; CHECK-GI-NEXT: sdiv w13, w8, w9
1801+
; CHECK-GI-NEXT: smov w8, v0.h[3]
1802+
; CHECK-GI-NEXT: smov w9, v3.h[3]
1803+
; CHECK-GI-NEXT: sdiv w12, w8, w9
1804+
; CHECK-GI-NEXT: smov w8, v0.h[4]
1805+
; CHECK-GI-NEXT: smov w9, v3.h[4]
1806+
; CHECK-GI-NEXT: sdiv w11, w8, w9
1807+
; CHECK-GI-NEXT: smov w8, v0.h[5]
1808+
; CHECK-GI-NEXT: smov w9, v3.h[5]
1809+
; CHECK-GI-NEXT: sdiv w10, w8, w9
1810+
; CHECK-GI-NEXT: smov w8, v0.h[6]
1811+
; CHECK-GI-NEXT: smov w9, v3.h[6]
1812+
; CHECK-GI-NEXT: movi v3.8h, #1
1813+
; CHECK-GI-NEXT: smov w17, v3.h[0]
1814+
; CHECK-GI-NEXT: smov w18, v3.h[1]
1815+
; CHECK-GI-NEXT: smov w0, v3.h[2]
1816+
; CHECK-GI-NEXT: smov w1, v3.h[3]
1817+
; CHECK-GI-NEXT: smov w2, v3.h[4]
1818+
; CHECK-GI-NEXT: smov w3, v3.h[5]
1819+
; CHECK-GI-NEXT: sdiv w8, w8, w9
1820+
; CHECK-GI-NEXT: smov w9, v0.h[7]
1821+
; CHECK-GI-NEXT: fmov s0, w14
1822+
; CHECK-GI-NEXT: mov v0.h[1], w15
1823+
; CHECK-GI-NEXT: smov w15, v1.h[6]
1824+
; CHECK-GI-NEXT: mov v0.h[2], w13
1825+
; CHECK-GI-NEXT: sdiv w9, w9, w16
1826+
; CHECK-GI-NEXT: smov w16, v1.h[0]
1827+
; CHECK-GI-NEXT: mov v0.h[3], w12
1828+
; CHECK-GI-NEXT: smov w12, v1.h[7]
1829+
; CHECK-GI-NEXT: mov v0.h[4], w11
1830+
; CHECK-GI-NEXT: sdiv w16, w16, w17
1831+
; CHECK-GI-NEXT: smov w17, v1.h[1]
1832+
; CHECK-GI-NEXT: mov v0.h[5], w10
1833+
; CHECK-GI-NEXT: mov v0.h[6], w8
1834+
; CHECK-GI-NEXT: sdiv w17, w17, w18
1835+
; CHECK-GI-NEXT: smov w18, v1.h[2]
1836+
; CHECK-GI-NEXT: fmov s2, w16
1837+
; CHECK-GI-NEXT: smov w16, v3.h[6]
1838+
; CHECK-GI-NEXT: mov v0.h[7], w9
1839+
; CHECK-GI-NEXT: sdiv w18, w18, w0
1840+
; CHECK-GI-NEXT: smov w0, v1.h[3]
1841+
; CHECK-GI-NEXT: mov v2.h[1], w17
1842+
; CHECK-GI-NEXT: sdiv w0, w0, w1
1843+
; CHECK-GI-NEXT: smov w1, v1.h[4]
1844+
; CHECK-GI-NEXT: mov v2.h[2], w18
1845+
; CHECK-GI-NEXT: sdiv w1, w1, w2
1846+
; CHECK-GI-NEXT: smov w2, v1.h[5]
1847+
; CHECK-GI-NEXT: mov v2.h[3], w0
1848+
; CHECK-GI-NEXT: sdiv w14, w2, w3
1849+
; CHECK-GI-NEXT: mov v2.h[4], w1
1850+
; CHECK-GI-NEXT: sdiv w13, w15, w16
1851+
; CHECK-GI-NEXT: smov w15, v3.h[7]
1852+
; CHECK-GI-NEXT: mov v2.h[5], w14
1853+
; CHECK-GI-NEXT: sdiv w10, w12, w15
1854+
; CHECK-GI-NEXT: mov v2.h[6], w13
1855+
; CHECK-GI-NEXT: mov v2.h[7], w10
1856+
; CHECK-GI-NEXT: mov v1.16b, v2.16b
1857+
; CHECK-GI-NEXT: ret
1858+
%zero_and_ones = shufflevector <16 x i16> zeroinitializer, <16 x i16> splat (i16 1), <16 x i32> <i32 0, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
1859+
%div = sdiv <16 x i16> %x, %zero_and_ones
1860+
ret <16 x i16> %div
1861+
}

0 commit comments

Comments
 (0)