@@ -457,21 +457,25 @@ define i8 @umin_of_nots_uses(i8 %x, i8 %y) {
457
457
ret i8 %m
458
458
}
459
459
460
+ ; Canonicalize 'not' after min/max.
461
+
460
462
define i8 @smax_of_not_and_const (i8 %x ) {
461
463
; CHECK-LABEL: @smax_of_not_and_const(
462
- ; CHECK-NEXT: [[NOTX :%.*]] = xor i8 [[X:%.*]], -1
463
- ; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[NOTX ]], i8 42)
464
+ ; CHECK-NEXT: [[TMP1 :%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 -43)
465
+ ; CHECK-NEXT: [[M:%.*]] = xor i8 [[TMP1 ]], -1
464
466
; CHECK-NEXT: ret i8 [[M]]
465
467
;
466
468
%notx = xor i8 %x , -1
467
469
%m = call i8 @llvm.smax.i8 (i8 %notx , i8 42 )
468
470
ret i8 %m
469
471
}
470
472
473
+ ; Vectors are ok (including undef lanes of not ops and min/max constant operand)
474
+
471
475
define <3 x i8 > @smin_of_not_and_const (<3 x i8 > %x ) {
472
476
; CHECK-LABEL: @smin_of_not_and_const(
473
- ; CHECK-NEXT: [[NOTX :%.*]] = xor <3 x i8> [[X:%.*]], <i8 -1 , i8 -1 , i8 undef>
474
- ; CHECK-NEXT: [[M:%.*]] = call <3 x i8> @llvm.smin.v3i8(<3 x i8> [[NOTX ]], <3 x i8> <i8 42 , i8 undef , i8 43>)
477
+ ; CHECK-NEXT: [[TMP1 :%.*]] = call <3 x i8> @llvm.smax.v3i8(<3 x i8> [[X:%.*]], <3 x i8> <i8 -43 , i8 undef , i8 -44>)
478
+ ; CHECK-NEXT: [[M:%.*]] = xor <3 x i8> [[TMP1 ]], <i8 -1 , i8 -1 , i8 -1>
475
479
; CHECK-NEXT: ret <3 x i8> [[M]]
476
480
;
477
481
%notx = xor <3 x i8 > %x , <i8 -1 , i8 -1 , i8 undef >
@@ -481,8 +485,8 @@ define <3 x i8> @smin_of_not_and_const(<3 x i8> %x) {
481
485
482
486
define i8 @umax_of_not_and_const (i8 %x ) {
483
487
; CHECK-LABEL: @umax_of_not_and_const(
484
- ; CHECK-NEXT: [[NOTX :%.*]] = xor i8 [[X:%.*]], -1
485
- ; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[NOTX ]], i8 44)
488
+ ; CHECK-NEXT: [[TMP1 :%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 -45)
489
+ ; CHECK-NEXT: [[M:%.*]] = xor i8 [[TMP1 ]], -1
486
490
; CHECK-NEXT: ret i8 [[M]]
487
491
;
488
492
%notx = xor i8 %x , -1
@@ -492,15 +496,17 @@ define i8 @umax_of_not_and_const(i8 %x) {
492
496
493
497
define i8 @umin_of_not_and_const (i8 %x ) {
494
498
; CHECK-LABEL: @umin_of_not_and_const(
495
- ; CHECK-NEXT: [[NOTX :%.*]] = xor i8 [[X:%.*]], -1
496
- ; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[NOTX ]], i8 -45)
499
+ ; CHECK-NEXT: [[TMP1 :%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 44)
500
+ ; CHECK-NEXT: [[M:%.*]] = xor i8 [[TMP1 ]], -1
497
501
; CHECK-NEXT: ret i8 [[M]]
498
502
;
499
503
%notx = xor i8 %x , -1
500
504
%m = call i8 @llvm.umin.i8 (i8 -45 , i8 %notx )
501
505
ret i8 %m
502
506
}
503
507
508
+ ; Negative test - too many uses
509
+
504
510
define i8 @umin_of_not_and_const_uses (i8 %x ) {
505
511
; CHECK-LABEL: @umin_of_not_and_const_uses(
506
512
; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
0 commit comments