Skip to content

Commit 489e75b

Browse files
committed
Fixups
1 parent f579776 commit 489e75b

File tree

2 files changed

+43
-44
lines changed

2 files changed

+43
-44
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3533,16 +3533,18 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
35333533
// -> (and cond, (icmp eq Other, 0))
35343534
// (icmp ne (or (select cond, NonZero, 0), Other), 0)
35353535
// -> (or cond, (icmp ne Other, 0))
3536-
Value *Cond, *TV, *FV, *Other;
3536+
Value *Cond, *TV, *FV, *Other, *Sel;
35373537
if (C.isZero() &&
35383538
match(BO,
3539-
m_OneUse(m_c_Or(m_Select(m_Value(Cond), m_Value(TV), m_Value(FV)),
3539+
m_OneUse(m_c_Or(m_CombineAnd(m_Value(Sel),
3540+
m_Select(m_Value(Cond), m_Value(TV),
3541+
m_Value(FV))),
35403542
m_Value(Other))))) {
35413543
const SimplifyQuery Q = SQ.getWithInstruction(&Cmp);
35423544
// Easy case is if eq/ne matches whether 0 is trueval/falseval.
35433545
if (Pred == ICmpInst::ICMP_EQ
3544-
? (match(TV, m_SpecificInt(C)) && isKnownNonZero(FV, Q))
3545-
: (match(FV, m_SpecificInt(C)) && isKnownNonZero(TV, Q))) {
3546+
? (match(TV, m_Zero()) && isKnownNonZero(FV, Q))
3547+
: (match(FV, m_Zero()) && isKnownNonZero(TV, Q))) {
35463548
Value *Cmp = Builder.CreateICmp(
35473549
Pred, Other, Constant::getNullValue(Other->getType()));
35483550
return BinaryOperator::Create(
@@ -3556,28 +3558,21 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
35563558
// -> (or (not cond), (icmp ne Other, 0))
35573559
// (icmp eq (or (select cond, NonZero, 0), Other), 0)
35583560
// -> (and (not cond), (icmp eq Other, 0))
3559-
if (Pred == ICmpInst::ICMP_EQ
3560-
? (match(FV, m_SpecificInt(C)) && isKnownNonZero(TV, Q))
3561-
: (match(TV, m_SpecificInt(C)) && isKnownNonZero(FV, Q))) {
3562-
Value *NotCond = nullptr;
3563-
// If the select is one use, we are essentially replacing select with
3564-
// `(not Cond)`.
3565-
auto SelectMatcher =
3566-
m_Select(m_Specific(Cond), m_Specific(TV), m_Specific(FV));
3567-
if (match(BO, m_c_Or(m_OneUse(SelectMatcher), m_Value())))
3568-
NotCond = Builder.CreateNot(Cond);
3569-
// Otherwise, see if we can get NotCond for free.
3570-
else if (match(BO, m_c_Or(SelectMatcher, m_Value())))
3571-
NotCond =
3572-
getFreelyInverted(Cond, /*WillInvertAllUses=*/false, &Builder);
3573-
3574-
if (NotCond) {
3575-
Value *Cmp = Builder.CreateICmp(
3576-
Pred, Other, Constant::getNullValue(Other->getType()));
3577-
return BinaryOperator::Create(
3578-
Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or,
3579-
Cmp, NotCond);
3580-
}
3561+
//
3562+
// Only do this if the inner select has one use, in which case we are
3563+
// replacing `select` with `(not cond)`. Otherwise, we will create more
3564+
// uses. NB: Trying to freely invert cond doesn't make sense here, as if
3565+
// cond was freely invertable, the select arms would have been inverted.
3566+
if (Sel->hasOneUse() &&
3567+
(Pred == ICmpInst::ICMP_EQ
3568+
? (match(FV, m_Zero()) && isKnownNonZero(TV, Q))
3569+
: (match(TV, m_Zero()) && isKnownNonZero(FV, Q)))) {
3570+
Value *NotCond = Builder.CreateNot(Cond);
3571+
Value *Cmp = Builder.CreateICmp(
3572+
Pred, Other, Constant::getNullValue(Other->getType()));
3573+
return BinaryOperator::Create(
3574+
Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,
3575+
NotCond);
35813576
}
35823577
}
35833578
break;

llvm/test/Transforms/InstCombine/icmp-or-of-select-with-zero.ll

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ declare void @use.i8(i8)
55
declare void @use.i1(i1)
66
define i1 @src_tv_eq(i1 %c0, i8 %x, i8 %yy) {
77
; CHECK-LABEL: @src_tv_eq(
8-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX:%.*]], 0
9-
; CHECK-NEXT: [[R1:%.*]] = and i1 [[R]], [[C0:%.*]]
10-
; CHECK-NEXT: ret i1 [[R1]]
8+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
9+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[C0:%.*]]
10+
; CHECK-NEXT: ret i1 [[R]]
1111
;
1212
%y = add nuw i8 %yy, 1
1313
%sel = select i1 %c0, i8 0, i8 %y
@@ -50,9 +50,9 @@ define i1 @src_tv_eq_fail_tv_nonzero(i1 %c0, i8 %x, i8 %yy) {
5050

5151
define i1 @src_fv_ne(i1 %c0, i8 %x, i8 %yy) {
5252
; CHECK-LABEL: @src_fv_ne(
53-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX:%.*]], 0
54-
; CHECK-NEXT: [[R1:%.*]] = or i1 [[R]], [[C0:%.*]]
55-
; CHECK-NEXT: ret i1 [[R1]]
53+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
54+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[C0:%.*]]
55+
; CHECK-NEXT: ret i1 [[R]]
5656
;
5757
%y = add nuw i8 %yy, 1
5858
%sel = select i1 %c0, i8 %y, i8 0
@@ -79,9 +79,9 @@ define i1 @src_fv_ne_fail_maybe_zero(i1 %c0, i8 %x, i8 %yy) {
7979
define i1 @src_tv_ne(i1 %c0, i8 %x, i8 %yy) {
8080
; CHECK-LABEL: @src_tv_ne(
8181
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0:%.*]], true
82-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX:%.*]], 0
83-
; CHECK-NEXT: [[R1:%.*]] = or i1 [[R]], [[TMP1]]
84-
; CHECK-NEXT: ret i1 [[R1]]
82+
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[X:%.*]], 0
83+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP2]], [[TMP1]]
84+
; CHECK-NEXT: ret i1 [[R]]
8585
;
8686
%y = add nuw i8 %yy, 1
8787
%sel = select i1 %c0, i8 0, i8 %y
@@ -108,9 +108,9 @@ define i1 @src_tv_ne_fail_cmp_nonzero(i1 %c0, i8 %x, i8 %yy) {
108108
define i1 @src_fv_eq(i1 %c0, i8 %x, i8 %yy) {
109109
; CHECK-LABEL: @src_fv_eq(
110110
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0:%.*]], true
111-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX:%.*]], 0
112-
; CHECK-NEXT: [[R1:%.*]] = and i1 [[R]], [[TMP1]]
113-
; CHECK-NEXT: ret i1 [[R1]]
111+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0
112+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP1]]
113+
; CHECK-NEXT: ret i1 [[R]]
114114
;
115115
%y = add nuw i8 %yy, 1
116116
%sel = select i1 %c0, i8 %y, i8 0
@@ -169,10 +169,10 @@ define i1 @src_fv_eq_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
169169
; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
170170
; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
171171
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0]], true
172-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX:%.*]], 0
173-
; CHECK-NEXT: [[R1:%.*]] = and i1 [[R]], [[TMP1]]
172+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0
173+
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP1]]
174174
; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]])
175-
; CHECK-NEXT: ret i1 [[R1]]
175+
; CHECK-NEXT: ret i1 [[R]]
176176
;
177177
%c0 = icmp ugt i8 %a, %b
178178
%y = add nuw i8 %yy, 1
@@ -186,6 +186,9 @@ define i1 @src_fv_eq_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
186186
ret i1 %r
187187
}
188188

189+
190+
191+
189192
define i1 @src_fv_eq_invert2_fail_wrong_binop(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
190193
; CHECK-LABEL: @src_fv_eq_invert2_fail_wrong_binop(
191194
; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
@@ -260,6 +263,7 @@ define i1 @src_fv_eq_invert3(i8 %a, i8 %b, i8 %x, i8 %yy) {
260263
ret i1 %r
261264
}
262265

266+
263267
define i1 @src_tv_ne_invert(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
264268
; CHECK-LABEL: @src_tv_ne_invert(
265269
; CHECK-NEXT: [[NOT_C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
@@ -269,11 +273,11 @@ define i1 @src_tv_ne_invert(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
269273
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C0]], i8 [[Y]], i8 0
270274
; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
271275
; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
272-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX:%.*]], 0
273-
; CHECK-NEXT: [[R1:%.*]] = or i1 [[R]], [[NOT_C0]]
276+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
277+
; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[NOT_C0]]
274278
; CHECK-NEXT: call void @use.i8(i8 [[SEL]])
275279
; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]])
276-
; CHECK-NEXT: ret i1 [[R1]]
280+
; CHECK-NEXT: ret i1 [[R]]
277281
;
278282
%not_c0 = icmp ugt i8 %a, %b
279283
call void @use.i1(i1 %not_c0)

0 commit comments

Comments
 (0)