Skip to content

Commit f16320b

Browse files
committed
[NFC][InstCombine] Add test coverage for @llvm.uadd.sat canonicalization
The non-strict variants are already handled because they are canonicalized to strict variants by swapping hands in both the select and icmp, and the fold simply considers that strictness is irrelevant here. But that isn't actually true for the last pattern, as PR48390 reports.
1 parent 398f29f commit f16320b

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

llvm/test/Transforms/InstCombine/saturating-add-sub.ll

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,17 @@ define i32 @uadd_sat(i32 %x, i32 %y) {
12081208
%r = select i1 %c, i32 -1, i32 %a
12091209
ret i32 %r
12101210
}
1211+
define i32 @uadd_sat_nonstrict(i32 %x, i32 %y) {
1212+
; CHECK-LABEL: @uadd_sat_nonstrict(
1213+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
1214+
; CHECK-NEXT: ret i32 [[TMP1]]
1215+
;
1216+
%notx = xor i32 %x, -1
1217+
%a = add i32 %y, %x
1218+
%c = icmp ule i32 %notx, %y
1219+
%r = select i1 %c, i32 -1, i32 %a
1220+
ret i32 %r
1221+
}
12111222

12121223
define i32 @uadd_sat_commute_add(i32 %xp, i32 %y) {
12131224
; CHECK-LABEL: @uadd_sat_commute_add(
@@ -1236,6 +1247,19 @@ define i32 @uadd_sat_ugt(i32 %x, i32 %yp) {
12361247
%r = select i1 %c, i32 -1, i32 %a
12371248
ret i32 %r
12381249
}
1250+
define i32 @uadd_sat_uge(i32 %x, i32 %yp) {
1251+
; CHECK-LABEL: @uadd_sat_uge(
1252+
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1253+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1254+
; CHECK-NEXT: ret i32 [[TMP1]]
1255+
;
1256+
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1257+
%notx = xor i32 %x, -1
1258+
%a = add i32 %y, %x
1259+
%c = icmp uge i32 %y, %notx
1260+
%r = select i1 %c, i32 -1, i32 %a
1261+
ret i32 %r
1262+
}
12391263

12401264
define <2 x i32> @uadd_sat_ugt_commute_add(<2 x i32> %xp, <2 x i32> %yp) {
12411265
; CHECK-LABEL: @uadd_sat_ugt_commute_add(
@@ -1267,6 +1291,20 @@ define i32 @uadd_sat_commute_select(i32 %x, i32 %yp) {
12671291
ret i32 %r
12681292
}
12691293

1294+
define i32 @uadd_sat_commute_select_nonstrict(i32 %x, i32 %yp) {
1295+
; CHECK-LABEL: @uadd_sat_commute_select_nonstrict(
1296+
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1297+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1298+
; CHECK-NEXT: ret i32 [[TMP1]]
1299+
;
1300+
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1301+
%notx = xor i32 %x, -1
1302+
%a = add i32 %y, %x
1303+
%c = icmp ule i32 %y, %notx
1304+
%r = select i1 %c, i32 %a, i32 -1
1305+
ret i32 %r
1306+
}
1307+
12701308
define i32 @uadd_sat_commute_select_commute_add(i32 %xp, i32 %yp) {
12711309
; CHECK-LABEL: @uadd_sat_commute_select_commute_add(
12721310
; CHECK-NEXT: [[X:%.*]] = urem i32 42, [[XP:%.*]]
@@ -1354,6 +1392,19 @@ define i32 @uadd_sat_not(i32 %x, i32 %y) {
13541392
ret i32 %r
13551393
}
13561394

1395+
define i32 @uadd_sat_not_nonstrict(i32 %x, i32 %y) {
1396+
; CHECK-LABEL: @uadd_sat_not_nonstrict(
1397+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1398+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1399+
; CHECK-NEXT: ret i32 [[TMP1]]
1400+
;
1401+
%notx = xor i32 %x, -1
1402+
%a = add i32 %notx, %y
1403+
%c = icmp ule i32 %x, %y
1404+
%r = select i1 %c, i32 -1, i32 %a
1405+
ret i32 %r
1406+
}
1407+
13571408
define i32 @uadd_sat_not_commute_add(i32 %xp, i32 %yp) {
13581409
; CHECK-LABEL: @uadd_sat_not_commute_add(
13591410
; CHECK-NEXT: [[X:%.*]] = srem i32 42, [[XP:%.*]]
@@ -1384,6 +1435,19 @@ define i32 @uadd_sat_not_ugt(i32 %x, i32 %y) {
13841435
ret i32 %r
13851436
}
13861437

1438+
define i32 @uadd_sat_not_uge(i32 %x, i32 %y) {
1439+
; CHECK-LABEL: @uadd_sat_not_uge(
1440+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1441+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1442+
; CHECK-NEXT: ret i32 [[TMP1]]
1443+
;
1444+
%notx = xor i32 %x, -1
1445+
%a = add i32 %notx, %y
1446+
%c = icmp uge i32 %y, %x
1447+
%r = select i1 %c, i32 -1, i32 %a
1448+
ret i32 %r
1449+
}
1450+
13871451
define <2 x i32> @uadd_sat_not_ugt_commute_add(<2 x i32> %x, <2 x i32> %yp) {
13881452
; CHECK-LABEL: @uadd_sat_not_ugt_commute_add(
13891453
; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i32> [[YP:%.*]], <i32 2442, i32 4242>
@@ -1412,6 +1476,19 @@ define i32 @uadd_sat_not_commute_select(i32 %x, i32 %y) {
14121476
ret i32 %r
14131477
}
14141478

1479+
define i32 @uadd_sat_not_commute_select_nonstrict(i32 %x, i32 %y) {
1480+
; CHECK-LABEL: @uadd_sat_not_commute_select_nonstrict(
1481+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1482+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1483+
; CHECK-NEXT: ret i32 [[TMP1]]
1484+
;
1485+
%notx = xor i32 %x, -1
1486+
%a = add i32 %notx, %y
1487+
%c = icmp ule i32 %y, %x
1488+
%r = select i1 %c, i32 %a, i32 -1
1489+
ret i32 %r
1490+
}
1491+
14151492
define i32 @uadd_sat_not_commute_select_commute_add(i32 %x, i32 %yp) {
14161493
; CHECK-LABEL: @uadd_sat_not_commute_select_commute_add(
14171494
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 42, [[YP:%.*]]
@@ -1457,6 +1534,19 @@ define i32 @uadd_sat_not_commute_select_ugt_commute_add(i32 %x, i32 %y) {
14571534
ret i32 %r
14581535
}
14591536

1537+
define i32 @uadd_sat_not_commute_select_uge_commute_add(i32 %x, i32 %y) {
1538+
; CHECK-LABEL: @uadd_sat_not_commute_select_uge_commute_add(
1539+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1540+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1541+
; CHECK-NEXT: ret i32 [[TMP1]]
1542+
;
1543+
%notx = xor i32 %x, -1
1544+
%a = add i32 %notx, %y
1545+
%c = icmp uge i32 %x, %y
1546+
%r = select i1 %c, i32 %a, i32 -1
1547+
ret i32 %r
1548+
}
1549+
14601550
define i32 @uadd_sat_constant(i32 %x) {
14611551
; CHECK-LABEL: @uadd_sat_constant(
14621552
; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 42
@@ -1697,3 +1787,91 @@ define i32 @unsigned_sat_constant_using_min_wrong_constant(i32 %x) {
16971787
%r = add i32 %s, -42
16981788
ret i32 %r
16991789
}
1790+
1791+
define i32 @uadd_sat_via_add(i32 %x, i32 %y) {
1792+
; CHECK-LABEL: @uadd_sat_via_add(
1793+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1794+
; CHECK-NEXT: ret i32 [[TMP1]]
1795+
;
1796+
%a = add i32 %x, %y
1797+
%c = icmp ult i32 %a, %y
1798+
%r = select i1 %c, i32 -1, i32 %a
1799+
ret i32 %r
1800+
}
1801+
1802+
define i32 @uadd_sat_via_add_nonstrict(i32 %x, i32 %y) {
1803+
; CHECK-LABEL: @uadd_sat_via_add_nonstrict(
1804+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1805+
; CHECK-NEXT: ret i32 [[TMP1]]
1806+
;
1807+
%a = add i32 %x, %y
1808+
%c = icmp ule i32 %a, %y
1809+
%r = select i1 %c, i32 -1, i32 %a
1810+
ret i32 %r
1811+
}
1812+
1813+
define i32 @uadd_sat_via_add_swapped_select(i32 %x, i32 %y) {
1814+
; CHECK-LABEL: @uadd_sat_via_add_swapped_select(
1815+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1816+
; CHECK-NEXT: ret i32 [[TMP1]]
1817+
;
1818+
%a = add i32 %x, %y
1819+
%c = icmp uge i32 %a, %y
1820+
%r = select i1 %c, i32 %a, i32 -1
1821+
ret i32 %r
1822+
}
1823+
1824+
define i32 @uadd_sat_via_add_swapped_select_strict(i32 %x, i32 %y) {
1825+
; CHECK-LABEL: @uadd_sat_via_add_swapped_select_strict(
1826+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1827+
; CHECK-NEXT: ret i32 [[TMP1]]
1828+
;
1829+
%a = add i32 %x, %y
1830+
%c = icmp ugt i32 %a, %y
1831+
%r = select i1 %c, i32 %a, i32 -1
1832+
ret i32 %r
1833+
}
1834+
1835+
define i32 @uadd_sat_via_add_swapped_cmp(i32 %x, i32 %y) {
1836+
; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp(
1837+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1838+
; CHECK-NEXT: ret i32 [[TMP1]]
1839+
;
1840+
%a = add i32 %x, %y
1841+
%c = icmp ugt i32 %y, %a
1842+
%r = select i1 %c, i32 -1, i32 %a
1843+
ret i32 %r
1844+
}
1845+
1846+
define i32 @uadd_sat_via_add_swapped_cmp_nonstrict(i32 %x, i32 %y) {
1847+
; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_nonstrict(
1848+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1849+
; CHECK-NEXT: ret i32 [[TMP1]]
1850+
;
1851+
%a = add i32 %x, %y
1852+
%c = icmp uge i32 %y, %a
1853+
%r = select i1 %c, i32 -1, i32 %a
1854+
ret i32 %r
1855+
}
1856+
1857+
define i32 @uadd_sat_via_add_swapped_cmp_nonstric(i32 %x, i32 %y) {
1858+
; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_nonstric(
1859+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1860+
; CHECK-NEXT: ret i32 [[TMP1]]
1861+
;
1862+
%a = add i32 %x, %y
1863+
%c = icmp ule i32 %y, %a
1864+
%r = select i1 %c, i32 %a, i32 -1
1865+
ret i32 %r
1866+
}
1867+
1868+
define i32 @uadd_sat_via_add_swapped_cmp_select_nonstrict(i32 %x, i32 %y) {
1869+
; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_select_nonstrict(
1870+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
1871+
; CHECK-NEXT: ret i32 [[TMP1]]
1872+
;
1873+
%a = add i32 %x, %y
1874+
%c = icmp ult i32 %y, %a
1875+
%r = select i1 %c, i32 %a, i32 -1
1876+
ret i32 %r
1877+
}

0 commit comments

Comments
 (0)