Skip to content

Commit 934376d

Browse files
LebedevRItstellar
authored andcommitted
[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. (cherry picked from commit f16320b)
1 parent fc23bc9 commit 934376d

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
@@ -1211,6 +1211,17 @@ define i32 @uadd_sat(i32 %x, i32 %y) {
12111211
%r = select i1 %c, i32 -1, i32 %a
12121212
ret i32 %r
12131213
}
1214+
define i32 @uadd_sat_nonstrict(i32 %x, i32 %y) {
1215+
; CHECK-LABEL: @uadd_sat_nonstrict(
1216+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
1217+
; CHECK-NEXT: ret i32 [[TMP1]]
1218+
;
1219+
%notx = xor i32 %x, -1
1220+
%a = add i32 %y, %x
1221+
%c = icmp ule i32 %notx, %y
1222+
%r = select i1 %c, i32 -1, i32 %a
1223+
ret i32 %r
1224+
}
12141225

12151226
define i32 @uadd_sat_commute_add(i32 %xp, i32 %y) {
12161227
; CHECK-LABEL: @uadd_sat_commute_add(
@@ -1239,6 +1250,19 @@ define i32 @uadd_sat_ugt(i32 %x, i32 %yp) {
12391250
%r = select i1 %c, i32 -1, i32 %a
12401251
ret i32 %r
12411252
}
1253+
define i32 @uadd_sat_uge(i32 %x, i32 %yp) {
1254+
; CHECK-LABEL: @uadd_sat_uge(
1255+
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1256+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1257+
; CHECK-NEXT: ret i32 [[TMP1]]
1258+
;
1259+
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1260+
%notx = xor i32 %x, -1
1261+
%a = add i32 %y, %x
1262+
%c = icmp uge i32 %y, %notx
1263+
%r = select i1 %c, i32 -1, i32 %a
1264+
ret i32 %r
1265+
}
12421266

12431267
define <2 x i32> @uadd_sat_ugt_commute_add(<2 x i32> %xp, <2 x i32> %yp) {
12441268
; CHECK-LABEL: @uadd_sat_ugt_commute_add(
@@ -1270,6 +1294,20 @@ define i32 @uadd_sat_commute_select(i32 %x, i32 %yp) {
12701294
ret i32 %r
12711295
}
12721296

1297+
define i32 @uadd_sat_commute_select_nonstrict(i32 %x, i32 %yp) {
1298+
; CHECK-LABEL: @uadd_sat_commute_select_nonstrict(
1299+
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1300+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1301+
; CHECK-NEXT: ret i32 [[TMP1]]
1302+
;
1303+
%y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1304+
%notx = xor i32 %x, -1
1305+
%a = add i32 %y, %x
1306+
%c = icmp ule i32 %y, %notx
1307+
%r = select i1 %c, i32 %a, i32 -1
1308+
ret i32 %r
1309+
}
1310+
12731311
define i32 @uadd_sat_commute_select_commute_add(i32 %xp, i32 %yp) {
12741312
; CHECK-LABEL: @uadd_sat_commute_select_commute_add(
12751313
; CHECK-NEXT: [[X:%.*]] = urem i32 42, [[XP:%.*]]
@@ -1357,6 +1395,19 @@ define i32 @uadd_sat_not(i32 %x, i32 %y) {
13571395
ret i32 %r
13581396
}
13591397

1398+
define i32 @uadd_sat_not_nonstrict(i32 %x, i32 %y) {
1399+
; CHECK-LABEL: @uadd_sat_not_nonstrict(
1400+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1401+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1402+
; CHECK-NEXT: ret i32 [[TMP1]]
1403+
;
1404+
%notx = xor i32 %x, -1
1405+
%a = add i32 %notx, %y
1406+
%c = icmp ule i32 %x, %y
1407+
%r = select i1 %c, i32 -1, i32 %a
1408+
ret i32 %r
1409+
}
1410+
13601411
define i32 @uadd_sat_not_commute_add(i32 %xp, i32 %yp) {
13611412
; CHECK-LABEL: @uadd_sat_not_commute_add(
13621413
; CHECK-NEXT: [[X:%.*]] = srem i32 42, [[XP:%.*]]
@@ -1387,6 +1438,19 @@ define i32 @uadd_sat_not_ugt(i32 %x, i32 %y) {
13871438
ret i32 %r
13881439
}
13891440

1441+
define i32 @uadd_sat_not_uge(i32 %x, i32 %y) {
1442+
; CHECK-LABEL: @uadd_sat_not_uge(
1443+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1444+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1445+
; CHECK-NEXT: ret i32 [[TMP1]]
1446+
;
1447+
%notx = xor i32 %x, -1
1448+
%a = add i32 %notx, %y
1449+
%c = icmp uge i32 %y, %x
1450+
%r = select i1 %c, i32 -1, i32 %a
1451+
ret i32 %r
1452+
}
1453+
13901454
define <2 x i32> @uadd_sat_not_ugt_commute_add(<2 x i32> %x, <2 x i32> %yp) {
13911455
; CHECK-LABEL: @uadd_sat_not_ugt_commute_add(
13921456
; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i32> [[YP:%.*]], <i32 2442, i32 4242>
@@ -1415,6 +1479,19 @@ define i32 @uadd_sat_not_commute_select(i32 %x, i32 %y) {
14151479
ret i32 %r
14161480
}
14171481

1482+
define i32 @uadd_sat_not_commute_select_nonstrict(i32 %x, i32 %y) {
1483+
; CHECK-LABEL: @uadd_sat_not_commute_select_nonstrict(
1484+
; CHECK-NEXT: [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1485+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NOTX]], i32 [[Y:%.*]])
1486+
; CHECK-NEXT: ret i32 [[TMP1]]
1487+
;
1488+
%notx = xor i32 %x, -1
1489+
%a = add i32 %notx, %y
1490+
%c = icmp ule i32 %y, %x
1491+
%r = select i1 %c, i32 %a, i32 -1
1492+
ret i32 %r
1493+
}
1494+
14181495
define i32 @uadd_sat_not_commute_select_commute_add(i32 %x, i32 %yp) {
14191496
; CHECK-LABEL: @uadd_sat_not_commute_select_commute_add(
14201497
; CHECK-NEXT: [[Y:%.*]] = sdiv i32 42, [[YP:%.*]]
@@ -1460,6 +1537,19 @@ define i32 @uadd_sat_not_commute_select_ugt_commute_add(i32 %x, i32 %y) {
14601537
ret i32 %r
14611538
}
14621539

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

0 commit comments

Comments
 (0)