Skip to content

Commit a927bbe

Browse files
committed
[InstCombine] handle trunc to i1 in foldSelectICmpAndBinOp
1 parent a422bc7 commit a927bbe

File tree

2 files changed

+49
-42
lines changed

2 files changed

+49
-42
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -742,39 +742,47 @@ static Value *foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal,
742742
/// 1. The icmp predicate is inverted
743743
/// 2. The select operands are reversed
744744
/// 3. The magnitude of C2 and C1 are flipped
745-
static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
746-
Value *FalseVal,
747-
InstCombiner::BuilderTy &Builder) {
745+
static Value *foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal,
746+
Value *FalseVal,
747+
InstCombiner::BuilderTy &Builder) {
748748
// Only handle integer compares. Also, if this is a vector select, we need a
749749
// vector compare.
750750
if (!TrueVal->getType()->isIntOrIntVectorTy() ||
751-
TrueVal->getType()->isVectorTy() != IC->getType()->isVectorTy())
751+
TrueVal->getType()->isVectorTy() != CondVal->getType()->isVectorTy())
752752
return nullptr;
753753

754-
Value *CmpLHS = IC->getOperand(0);
755-
Value *CmpRHS = IC->getOperand(1);
756-
757754
unsigned C1Log;
758755
bool NeedAnd = false;
759-
CmpInst::Predicate Pred = IC->getPredicate();
760-
if (IC->isEquality()) {
761-
if (!match(CmpRHS, m_Zero()))
762-
return nullptr;
756+
CmpPredicate Pred;
757+
Value *CmpLHS, *CmpRHS;
763758

764-
const APInt *C1;
765-
if (!match(CmpLHS, m_And(m_Value(), m_Power2(C1))))
766-
return nullptr;
759+
if (match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)))) {
760+
if (ICmpInst::isEquality(Pred)) {
761+
if (!match(CmpRHS, m_Zero()))
762+
return nullptr;
767763

768-
C1Log = C1->logBase2();
769-
} else {
770-
auto Res = decomposeBitTestICmp(CmpLHS, CmpRHS, Pred);
771-
if (!Res || !Res->Mask.isPowerOf2())
772-
return nullptr;
764+
const APInt *C1;
765+
if (!match(CmpLHS, m_And(m_Value(), m_Power2(C1))))
766+
return nullptr;
773767

774-
CmpLHS = Res->X;
775-
Pred = Res->Pred;
776-
C1Log = Res->Mask.logBase2();
777-
NeedAnd = true;
768+
C1Log = C1->logBase2();
769+
} else {
770+
auto Res = decomposeBitTestICmp(CmpLHS, CmpRHS, Pred);
771+
if (!Res || !Res->Mask.isPowerOf2())
772+
return nullptr;
773+
774+
CmpLHS = Res->X;
775+
Pred = Res->Pred;
776+
C1Log = Res->Mask.logBase2();
777+
NeedAnd = true;
778+
}
779+
} else if (auto *Trunc = dyn_cast<TruncInst>(CondVal)) {
780+
CmpLHS = Trunc->getOperand(0);
781+
C1Log = 0;
782+
Pred = ICmpInst::ICMP_NE;
783+
NeedAnd = !Trunc->hasNoUnsignedWrap();
784+
} else {
785+
return nullptr;
778786
}
779787

780788
Value *Y, *V = CmpLHS;
@@ -808,7 +816,7 @@ static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
808816

809817
// Make sure we don't create more instructions than we save.
810818
if ((NeedShift + NeedXor + NeedZExtTrunc + NeedAnd) >
811-
(IC->hasOneUse() + BinOp->hasOneUse()))
819+
(CondVal->hasOneUse() + BinOp->hasOneUse()))
812820
return nullptr;
813821

814822
if (NeedAnd) {
@@ -1983,9 +1991,6 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19831991
if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal, Builder))
19841992
return V;
19851993

1986-
if (Value *V = foldSelectICmpAndBinOp(ICI, TrueVal, FalseVal, Builder))
1987-
return replaceInstUsesWith(SI, V);
1988-
19891994
if (Value *V = foldSelectICmpLshrAshr(ICI, TrueVal, FalseVal, Builder))
19901995
return replaceInstUsesWith(SI, V);
19911996

@@ -3943,6 +3948,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
39433948
if (Instruction *Result = foldSelectInstWithICmp(SI, ICI))
39443949
return Result;
39453950

3951+
if (Value *V = foldSelectICmpAndBinOp(CondVal, TrueVal, FalseVal, Builder))
3952+
return replaceInstUsesWith(SI, V);
3953+
39463954
if (Instruction *Add = foldAddSubSelect(SI, Builder))
39473955
return Add;
39483956
if (Instruction *Add = foldOverflowingAddSubSelect(SI, Builder))

llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,9 +1712,9 @@ define i8 @select_icmp_eq_and_1_0_lshr_tv(i8 %x, i8 %y) {
17121712

17131713
define i8 @select_trunc_or_2(i8 %x, i8 %y) {
17141714
; CHECK-LABEL: @select_trunc_or_2(
1715-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1
1716-
; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 2
1717-
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i8 [[OR]], i8 [[Y]]
1715+
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
1716+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 2
1717+
; CHECK-NEXT: [[SELECT:%.*]] = or i8 [[Y:%.*]], [[TMP2]]
17181718
; CHECK-NEXT: ret i8 [[SELECT]]
17191719
;
17201720
%trunc = trunc i8 %x to i1
@@ -1725,9 +1725,9 @@ define i8 @select_trunc_or_2(i8 %x, i8 %y) {
17251725

17261726
define i8 @select_not_trunc_or_2(i8 %x, i8 %y) {
17271727
; CHECK-LABEL: @select_not_trunc_or_2(
1728-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1
1729-
; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 2
1730-
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i8 [[OR]], i8 [[Y]]
1728+
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
1729+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 2
1730+
; CHECK-NEXT: [[SELECT:%.*]] = or i8 [[Y:%.*]], [[TMP2]]
17311731
; CHECK-NEXT: ret i8 [[SELECT]]
17321732
;
17331733
%trunc = trunc i8 %x to i1
@@ -1739,9 +1739,8 @@ define i8 @select_not_trunc_or_2(i8 %x, i8 %y) {
17391739

17401740
define i8 @select_trunc_nuw_or_2(i8 %x, i8 %y) {
17411741
; CHECK-LABEL: @select_trunc_nuw_or_2(
1742-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[X:%.*]] to i1
1743-
; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 2
1744-
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i8 [[OR]], i8 [[Y]]
1742+
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
1743+
; CHECK-NEXT: [[SELECT:%.*]] = or i8 [[Y:%.*]], [[TMP1]]
17451744
; CHECK-NEXT: ret i8 [[SELECT]]
17461745
;
17471746
%trunc = trunc nuw i8 %x to i1
@@ -1752,9 +1751,9 @@ define i8 @select_trunc_nuw_or_2(i8 %x, i8 %y) {
17521751

17531752
define i8 @select_trunc_nsw_or_2(i8 %x, i8 %y) {
17541753
; CHECK-LABEL: @select_trunc_nsw_or_2(
1755-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i8 [[X:%.*]] to i1
1756-
; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 2
1757-
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i8 [[OR]], i8 [[Y]]
1754+
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
1755+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 2
1756+
; CHECK-NEXT: [[SELECT:%.*]] = or i8 [[Y:%.*]], [[TMP2]]
17581757
; CHECK-NEXT: ret i8 [[SELECT]]
17591758
;
17601759
%trunc = trunc nsw i8 %x to i1
@@ -1765,9 +1764,9 @@ define i8 @select_trunc_nsw_or_2(i8 %x, i8 %y) {
17651764

17661765
define <2 x i8> @select_trunc_or_2_vec(<2 x i8> %x, <2 x i8> %y) {
17671766
; CHECK-LABEL: @select_trunc_or_2_vec(
1768-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i8> [[X:%.*]] to <2 x i1>
1769-
; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], splat (i8 2)
1770-
; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> [[TRUNC]], <2 x i8> [[OR]], <2 x i8> [[Y]]
1767+
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 1)
1768+
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], splat (i8 2)
1769+
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i8> [[Y:%.*]], [[TMP2]]
17711770
; CHECK-NEXT: ret <2 x i8> [[SELECT]]
17721771
;
17731772
%trunc = trunc <2 x i8> %x to <2 x i1>

0 commit comments

Comments
 (0)