@@ -1248,3 +1248,89 @@ define <4 x i32> @uadd_sat_constant_vec_commute_undefs(<4 x i32> %x) {
1248
1248
ret <4 x i32 > %r
1249
1249
}
1250
1250
1251
+ declare i32 @get_i32 ()
1252
+ declare <2 x i8 > @get_v2i8 ()
1253
+
1254
+ define i32 @unsigned_sat_variable_using_min_add (i32 %x ) {
1255
+ ; CHECK-LABEL: @unsigned_sat_variable_using_min_add(
1256
+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @get_i32()
1257
+ ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y]], -1
1258
+ ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[NOTY]], [[X:%.*]]
1259
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[X]], i32 [[NOTY]]
1260
+ ; CHECK-NEXT: [[R:%.*]] = add i32 [[S]], [[Y]]
1261
+ ; CHECK-NEXT: ret i32 [[R]]
1262
+ ;
1263
+ %y = call i32 @get_i32 () ; thwart complexity-based canonicalization
1264
+ %noty = xor i32 %y , -1
1265
+ %c = icmp ult i32 %x , %noty
1266
+ %s = select i1 %c , i32 %x , i32 %noty
1267
+ %r = add i32 %s , %y
1268
+ ret i32 %r
1269
+ }
1270
+
1271
+ define i32 @unsigned_sat_variable_using_min_commute_add (i32 %x ) {
1272
+ ; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_add(
1273
+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @get_i32()
1274
+ ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y]], -1
1275
+ ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[NOTY]], [[X:%.*]]
1276
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[X]], i32 [[NOTY]]
1277
+ ; CHECK-NEXT: [[R:%.*]] = add i32 [[Y]], [[S]]
1278
+ ; CHECK-NEXT: ret i32 [[R]]
1279
+ ;
1280
+ %y = call i32 @get_i32 () ; thwart complexity-based canonicalization
1281
+ %noty = xor i32 %y , -1
1282
+ %c = icmp ult i32 %x , %noty
1283
+ %s = select i1 %c , i32 %x , i32 %noty
1284
+ %r = add i32 %y , %s
1285
+ ret i32 %r
1286
+ }
1287
+
1288
+ define <2 x i8 > @unsigned_sat_variable_using_min_commute_select (<2 x i8 > %x ) {
1289
+ ; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_select(
1290
+ ; CHECK-NEXT: [[Y:%.*]] = call <2 x i8> @get_v2i8()
1291
+ ; CHECK-NEXT: [[NOTY:%.*]] = xor <2 x i8> [[Y]], <i8 -1, i8 -1>
1292
+ ; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[NOTY]], [[X:%.*]]
1293
+ ; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[NOTY]], <2 x i8> [[X]]
1294
+ ; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[S]], [[Y]]
1295
+ ; CHECK-NEXT: ret <2 x i8> [[R]]
1296
+ ;
1297
+ %y = call <2 x i8 > @get_v2i8 () ; thwart complexity-based canonicalization
1298
+ %noty = xor <2 x i8 > %y , <i8 -1 , i8 -1 >
1299
+ %c = icmp ult <2 x i8 > %noty , %x
1300
+ %s = select <2 x i1 > %c , <2 x i8 > %noty , <2 x i8 > %x
1301
+ %r = add <2 x i8 > %s , %y
1302
+ ret <2 x i8 > %r
1303
+ }
1304
+
1305
+ define <2 x i8 > @unsigned_sat_variable_using_min_commute_add_select (<2 x i8 > %x ) {
1306
+ ; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_add_select(
1307
+ ; CHECK-NEXT: [[Y:%.*]] = call <2 x i8> @get_v2i8()
1308
+ ; CHECK-NEXT: [[NOTY:%.*]] = xor <2 x i8> [[Y]], <i8 -1, i8 -1>
1309
+ ; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[NOTY]], [[X:%.*]]
1310
+ ; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i8> [[NOTY]], <2 x i8> [[X]]
1311
+ ; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[Y]], [[S]]
1312
+ ; CHECK-NEXT: ret <2 x i8> [[R]]
1313
+ ;
1314
+ %y = call <2 x i8 > @get_v2i8 () ; thwart complexity-based canonicalization
1315
+ %noty = xor <2 x i8 > %y , <i8 -1 , i8 -1 >
1316
+ %c = icmp ult <2 x i8 > %noty , %x
1317
+ %s = select <2 x i1 > %c , <2 x i8 > %noty , <2 x i8 > %x
1318
+ %r = add <2 x i8 > %y , %s
1319
+ ret <2 x i8 > %r
1320
+ }
1321
+
1322
+ ; If we have a constant operand, there's no commutativity variation.
1323
+
1324
+ define i32 @unsigned_sat_constant_using_min (i32 %x ) {
1325
+ ; CHECK-LABEL: @unsigned_sat_constant_using_min(
1326
+ ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], 42
1327
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[X]], i32 42
1328
+ ; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[S]], -43
1329
+ ; CHECK-NEXT: ret i32 [[R]]
1330
+ ;
1331
+ %c = icmp ult i32 %x , 42
1332
+ %s = select i1 %c , i32 %x , i32 42
1333
+ %r = add i32 %s , -43
1334
+ ret i32 %r
1335
+ }
1336
+
0 commit comments