Skip to content

Commit dd31a3b

Browse files
committed
[InstCombine] fold icmp of the sum of ext bool based on limited range
For the pattern `(zext i1 X) + (sext i1 Y)`, the constant range is [-1, 1]. We can simplify the pattern by logical operations. Like: ``` (zext i1 X) + (sext i1 Y) == -1 --> ~X & Y (zext i1 X) + (sext i1 Y) == 0 --> ~(X ^ Y) (zext i1 X) + (sext i1 Y) == 1 --> X & ~Y ``` And other predicates can the combination of these results: ``` (zext i1 X) + (sext i1 Y)) != -1 --> X | ~Y (zext i1 X) + (sext i1 Y)) s> -1 --> X | ~Y (zext i1 X) + (sext i1 Y)) u< -1 --> X | ~Y (zext i1 X) + (sext i1 Y)) s> 0 --> X & ~Y (zext i1 X) + (sext i1 Y)) s< 0 --> ~X & Y (zext i1 X) + (sext i1 Y)) != 1 --> ~X | Y (zext i1 X) + (sext i1 Y)) s< 1 --> ~X | Y (zext i1 X) + (sext i1 Y)) u> 1 --> ~X & Y ``` All alive proofs: https://alive2.llvm.org/ce/z/KmgDpF https://alive2.llvm.org/ce/z/fLwWa9 https://alive2.llvm.org/ce/z/ZKQn2P Fix: #59666 Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D143373
1 parent 06f0664 commit dd31a3b

File tree

3 files changed

+120
-66
lines changed

3 files changed

+120
-66
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5863,8 +5863,7 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
58635863

58645864
/// If one operand of an icmp is effectively a bool (value range of {0,1}),
58655865
/// then try to reduce patterns based on that limit.
5866-
static Instruction *foldICmpUsingBoolRange(ICmpInst &I,
5867-
InstCombiner::BuilderTy &Builder) {
5866+
Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) {
58685867
Value *X, *Y;
58695868
ICmpInst::Predicate Pred;
58705869

@@ -5880,6 +5879,59 @@ static Instruction *foldICmpUsingBoolRange(ICmpInst &I,
58805879
Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE)
58815880
return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y);
58825881

5882+
const APInt *C;
5883+
if (match(I.getOperand(0),
5884+
m_OneUse(m_c_Add(m_ZExt(m_Value(X)), m_SExt(m_Value(Y))))) &&
5885+
match(I.getOperand(1), m_APInt(C)) &&
5886+
X->getType()->isIntOrIntVectorTy(1) &&
5887+
Y->getType()->isIntOrIntVectorTy(1)) {
5888+
unsigned BitWidth = C->getBitWidth();
5889+
Pred = I.getPredicate();
5890+
APInt Zero = APInt::getZero(BitWidth);
5891+
APInt MinusOne = APInt::getAllOnes(BitWidth);
5892+
APInt One(BitWidth, 1);
5893+
if ((C->sgt(Zero) && Pred == ICmpInst::ICMP_SGT) ||
5894+
(C->slt(Zero) && Pred == ICmpInst::ICMP_SLT))
5895+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
5896+
if ((C->sgt(One) && Pred == ICmpInst::ICMP_SLT) ||
5897+
(C->slt(MinusOne) && Pred == ICmpInst::ICMP_SGT))
5898+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
5899+
5900+
APInt NewC = *C;
5901+
// canonicalize predicate to eq/ne
5902+
if ((*C == Zero && Pred == ICmpInst::ICMP_SLT) ||
5903+
(*C != Zero && *C != MinusOne && Pred == ICmpInst::ICMP_UGT)) {
5904+
// x s< 0 in [-1, 1] --> x == -1
5905+
// x u> 1(or any const !=0 !=-1) in [-1, 1] --> x == -1
5906+
NewC = MinusOne;
5907+
Pred = ICmpInst::ICMP_EQ;
5908+
} else if ((*C == MinusOne && Pred == ICmpInst::ICMP_SGT) ||
5909+
(*C != Zero && *C != One && Pred == ICmpInst::ICMP_ULT)) {
5910+
// x s> -1 in [-1, 1] --> x != -1
5911+
// x u< -1 in [-1, 1] --> x != -1
5912+
Pred = ICmpInst::ICMP_NE;
5913+
} else if (*C == Zero && Pred == ICmpInst::ICMP_SGT) {
5914+
// x s> 0 in [-1, 1] --> x == 1
5915+
NewC = One;
5916+
Pred = ICmpInst::ICMP_EQ;
5917+
} else if (*C == One && Pred == ICmpInst::ICMP_SLT) {
5918+
// x s< 1 in [-1, 1] --> x != 1
5919+
Pred = ICmpInst::ICMP_NE;
5920+
}
5921+
5922+
if (NewC == MinusOne) {
5923+
if (Pred == ICmpInst::ICMP_EQ)
5924+
return BinaryOperator::CreateAnd(Builder.CreateNot(X), Y);
5925+
if (Pred == ICmpInst::ICMP_NE)
5926+
return BinaryOperator::CreateOr(X, Builder.CreateNot(Y));
5927+
} else if (NewC == One) {
5928+
if (Pred == ICmpInst::ICMP_EQ)
5929+
return BinaryOperator::CreateAnd(X, Builder.CreateNot(Y));
5930+
if (Pred == ICmpInst::ICMP_NE)
5931+
return BinaryOperator::CreateOr(Builder.CreateNot(X), Y);
5932+
}
5933+
}
5934+
58835935
return nullptr;
58845936
}
58855937

@@ -6335,7 +6387,7 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
63356387
if (Instruction *Res = foldICmpWithDominatingICmp(I))
63366388
return Res;
63376389

6338-
if (Instruction *Res = foldICmpUsingBoolRange(I, Builder))
6390+
if (Instruction *Res = foldICmpUsingBoolRange(I))
63396391
return Res;
63406392

63416393
if (Instruction *Res = foldICmpUsingKnownBits(I))

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
565565
Instruction *foldICmpUsingKnownBits(ICmpInst &Cmp);
566566
Instruction *foldICmpWithDominatingICmp(ICmpInst &Cmp);
567567
Instruction *foldICmpWithConstant(ICmpInst &Cmp);
568+
Instruction *foldICmpUsingBoolRange(ICmpInst &I);
568569
Instruction *foldICmpInstWithConstant(ICmpInst &Cmp);
569570
Instruction *foldICmpInstWithConstantNotInt(ICmpInst &Cmp);
570571
Instruction *foldICmpInstWithConstantAllowUndef(ICmpInst &Cmp,

llvm/test/Transforms/InstCombine/icmp-range.ll

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -629,13 +629,11 @@ define i1 @ashr_uge_sub(i8 %b, i8 %x, i8 %y) {
629629
ret i1 %r
630630
}
631631

632+
; (zext i1 a) + (sext i1 b)) s< -1 --> false
633+
632634
define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {
633635
; CHECK-LABEL: @zext_sext_add_icmp_slt_minus1(
634-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
635-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
636-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
637-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], -1
638-
; CHECK-NEXT: ret i1 [[R]]
636+
; CHECK-NEXT: ret i1 false
639637
;
640638
%zext.a = zext i1 %a to i8
641639
%sext.b = sext i1 %b to i8
@@ -644,13 +642,11 @@ define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {
644642
ret i1 %r
645643
}
646644

645+
; (zext i1 a) + (sext i1 b)) s> 1 --> false
646+
647647
define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {
648648
; CHECK-LABEL: @zext_sext_add_icmp_sgt_1(
649-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
650-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
651-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
652-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], 1
653-
; CHECK-NEXT: ret i1 [[R]]
649+
; CHECK-NEXT: ret i1 false
654650
;
655651
%zext.a = zext i1 %a to i8
656652
%sext.b = sext i1 %b to i8
@@ -659,13 +655,11 @@ define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {
659655
ret i1 %r
660656
}
661657

658+
; (zext i1 a) + (sext i1 b)) s> -2 --> true
659+
662660
define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {
663661
; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus2(
664-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
665-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
666-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
667-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], -2
668-
; CHECK-NEXT: ret i1 [[R]]
662+
; CHECK-NEXT: ret i1 true
669663
;
670664
%zext.a = zext i1 %a to i8
671665
%sext.b = sext i1 %b to i8
@@ -674,13 +668,11 @@ define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {
674668
ret i1 %r
675669
}
676670

671+
; (zext i1 a) + (sext i1 b)) s< 2 --> true
672+
677673
define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {
678674
; CHECK-LABEL: @zext_sext_add_icmp_slt_2(
679-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
680-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
681-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
682-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 2
683-
; CHECK-NEXT: ret i1 [[R]]
675+
; CHECK-NEXT: ret i1 true
684676
;
685677
%zext.a = zext i1 %a to i8
686678
%sext.b = sext i1 %b to i8
@@ -689,13 +681,11 @@ define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {
689681
ret i1 %r
690682
}
691683

684+
; test case with i128
685+
692686
define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {
693687
; CHECK-LABEL: @zext_sext_add_icmp_i128(
694-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i128
695-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i128
696-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i128 [[ZEXT_A]], [[SEXT_B]]
697-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i128 [[ADD]], 9223372036854775808
698-
; CHECK-NEXT: ret i1 [[R]]
688+
; CHECK-NEXT: ret i1 false
699689
;
700690
%zext.a = zext i1 %a to i128
701691
%sext.b = sext i1 %b to i128
@@ -704,12 +694,12 @@ define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {
704694
ret i1 %r
705695
}
706696

697+
; (zext i1 a) + (sext i1 b)) == -1 --> ~a & b
698+
707699
define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {
708700
; CHECK-LABEL: @zext_sext_add_icmp_eq_minus1(
709-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
710-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
711-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
712-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], -1
701+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
702+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
713703
; CHECK-NEXT: ret i1 [[R]]
714704
;
715705
%zext.a = zext i1 %a to i8
@@ -719,12 +709,13 @@ define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {
719709
ret i1 %r
720710
}
721711

712+
713+
; (zext i1 a) + (sext i1 b)) != -1 --> a | ~b
714+
722715
define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {
723716
; CHECK-LABEL: @zext_sext_add_icmp_ne_minus1(
724-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
725-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
726-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
727-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], -1
717+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
718+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[A:%.*]]
728719
; CHECK-NEXT: ret i1 [[R]]
729720
;
730721
%zext.a = zext i1 %a to i8
@@ -734,10 +725,12 @@ define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {
734725
ret i1 %r
735726
}
736727

728+
; (zext i1 a) + (sext i1 b)) s> -1 --> a | ~b
729+
737730
define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {
738731
; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus1(
739-
; CHECK-NEXT: [[B_NOT:%.*]] = xor i1 [[B:%.*]], true
740-
; CHECK-NEXT: [[R:%.*]] = or i1 [[B_NOT]], [[A:%.*]]
732+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
733+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[A:%.*]]
741734
; CHECK-NEXT: ret i1 [[R]]
742735
;
743736
%zext.a = zext i1 %a to i8
@@ -747,12 +740,12 @@ define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {
747740
ret i1 %r
748741
}
749742

743+
; (zext i1 a) + (sext i1 b)) u< -1 --> a | ~b
744+
750745
define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {
751746
; CHECK-LABEL: @zext_sext_add_icmp_ult_minus1(
752-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
753-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
754-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
755-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], -1
747+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
748+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[A:%.*]]
756749
; CHECK-NEXT: ret i1 [[R]]
757750
;
758751
%zext.a = zext i1 %a to i8
@@ -762,12 +755,12 @@ define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {
762755
ret i1 %r
763756
}
764757

758+
; (zext i1 a) + (sext i1 b)) s> 0 --> a & ~b
759+
765760
define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {
766761
; CHECK-LABEL: @zext_sext_add_icmp_sgt_0(
767-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
768-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
769-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
770-
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[ADD]], 0
762+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
763+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[A:%.*]]
771764
; CHECK-NEXT: ret i1 [[R]]
772765
;
773766
%zext.a = zext i1 %a to i8
@@ -777,11 +770,13 @@ define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {
777770
ret i1 %r
778771
}
779772

773+
; (zext i1 a) + (sext i1 b)) s< 0 --> ~a & b
774+
780775
define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {
781776
; CHECK-LABEL: @zext_sext_add_icmp_slt_0(
782777
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
783-
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[B:%.*]]
784-
; CHECK-NEXT: ret i1 [[TMP2]]
778+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
779+
; CHECK-NEXT: ret i1 [[R]]
785780
;
786781
%zext.a = zext i1 %a to i8
787782
%sext.b = sext i1 %b to i8
@@ -790,12 +785,12 @@ define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {
790785
ret i1 %r
791786
}
792787

788+
; (zext i1 a) + (sext i1 b)) == 1 --> a & ~b
789+
793790
define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {
794791
; CHECK-LABEL: @zext_sext_add_icmp_eq_1(
795-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
796-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
797-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
798-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 1
792+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true
793+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[A:%.*]]
799794
; CHECK-NEXT: ret i1 [[R]]
800795
;
801796
%zext.a = zext i1 %a to i8
@@ -805,12 +800,12 @@ define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {
805800
ret i1 %r
806801
}
807802

803+
; (zext i1 a) + (sext i1 b)) != 1 --> ~a | b
804+
808805
define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {
809806
; CHECK-LABEL: @zext_sext_add_icmp_ne_1(
810-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
811-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
812-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
813-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[ADD]], 1
807+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
808+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
814809
; CHECK-NEXT: ret i1 [[R]]
815810
;
816811
%zext.a = zext i1 %a to i8
@@ -820,12 +815,12 @@ define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {
820815
ret i1 %r
821816
}
822817

818+
; (zext i1 a) + (sext i1 b)) s< 1 --> ~a | b
819+
823820
define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {
824821
; CHECK-LABEL: @zext_sext_add_icmp_slt_1(
825-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
826-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
827-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
828-
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 1
822+
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
823+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
829824
; CHECK-NEXT: ret i1 [[R]]
830825
;
831826
%zext.a = zext i1 %a to i8
@@ -835,11 +830,13 @@ define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {
835830
ret i1 %r
836831
}
837832

833+
; (zext i1 a) + (sext i1 b)) u> 1 --> ~a & b
834+
838835
define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {
839836
; CHECK-LABEL: @zext_sext_add_icmp_ugt_1(
840837
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true
841-
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[B:%.*]]
842-
; CHECK-NEXT: ret i1 [[TMP2]]
838+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
839+
; CHECK-NEXT: ret i1 [[R]]
843840
;
844841
%zext.a = zext i1 %a to i8
845842
%sext.b = sext i1 %b to i8
@@ -850,10 +847,8 @@ define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {
850847

851848
define <2 x i1> @vector_zext_sext_add_icmp_slt_1(<2 x i1> %a, <2 x i1> %b) {
852849
; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1(
853-
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8>
854-
; CHECK-NEXT: [[SEXT_B:%.*]] = sext <2 x i1> [[B:%.*]] to <2 x i8>
855-
; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[ZEXT_A]], [[SEXT_B]]
856-
; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i8> [[ADD]], <i8 1, i8 1>
850+
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[A:%.*]], <i1 true, i1 true>
851+
; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]]
857852
; CHECK-NEXT: ret <2 x i1> [[R]]
858853
;
859854
%zext.a = zext <2 x i1> %a to <2 x i8>
@@ -878,6 +873,8 @@ define <2 x i1> @vector_zext_sext_add_icmp_slt_1_poison(<2 x i1> %a, <2 x i1> %b
878873
ret <2 x i1> %r
879874
}
880875

876+
; Negative test, more than one use for icmp LHS
877+
881878
define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {
882879
; CHECK-LABEL: @zext_sext_add_icmp_slt_1_no_oneuse(
883880
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
@@ -895,6 +892,8 @@ define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {
895892
ret i1 %r
896893
}
897894

895+
; Negative test, icmp RHS is not a constant
896+
898897
define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {
899898
; CHECK-LABEL: @zext_sext_add_icmp_slt_1_rhs_not_const(
900899
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
@@ -910,6 +909,8 @@ define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {
910909
ret i1 %r
911910
}
912911

912+
; Negative test, ext source is not i1
913+
913914
define i1 @zext_sext_add_icmp_slt_1_type_not_i1(i2 %a, i1 %b) {
914915
; CHECK-LABEL: @zext_sext_add_icmp_slt_1_type_not_i1(
915916
; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i2 [[A:%.*]] to i8

0 commit comments

Comments
 (0)