Skip to content

Commit 349375d

Browse files
committed
[ConstraintElimination] Generalize OR matching.
Extend OR handling to traverse chains of ORs.
1 parent 89810ce commit 349375d

File tree

3 files changed

+39
-25
lines changed

3 files changed

+39
-25
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -578,18 +578,32 @@ void State::addInfoFor(BasicBlock &BB) {
578578
if (!Br || !Br->isConditional())
579579
return;
580580

581-
// If the condition is an OR of 2 compares and the false successor only has
582-
// the current block as predecessor, queue both negated conditions for the
581+
// If the condition is a chain of ORs and the false successor only has
582+
// the current block as predecessor, queue the negated conditions for the
583583
// false successor.
584584
Value *Op0, *Op1;
585-
if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) &&
586-
isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) {
585+
if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
587586
BasicBlock *FalseSuccessor = Br->getSuccessor(1);
588587
if (canAddSuccessor(BB, FalseSuccessor)) {
589-
WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op0),
590-
true);
591-
WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op1),
592-
true);
588+
SmallVector<Value *> CondWorkList;
589+
SmallPtrSet<Value *, 8> SeenCond;
590+
auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
591+
if (SeenCond.insert(V).second)
592+
CondWorkList.push_back(V);
593+
};
594+
QueueValue(Op0);
595+
QueueValue(Op1);
596+
while (!CondWorkList.empty()) {
597+
Value *Cur = CondWorkList.pop_back_val();
598+
if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
599+
WorkList.emplace_back(DT.getNode(FalseSuccessor), Cmp, true);
600+
continue;
601+
}
602+
if (match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
603+
QueueValue(Op0);
604+
QueueValue(Op1);
605+
}
606+
}
593607
}
594608
return;
595609
}

llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ define i4 @ptr_N_signed_positive(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %
492492
; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i16 [[STEP]]
493493
; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
494494
; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
495-
; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
495+
; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false
496496
; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
497497
; CHECK: exit:
498498
; CHECK-NEXT: ret i4 3

llvm/test/Transforms/ConstraintElimination/or.ll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,15 @@ define i1 @test_or_chain_ule_1(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {
145145
; CHECK: exit:
146146
; CHECK-NEXT: [[F_1:%.*]] = icmp ule i4 [[X]], [[Z]]
147147
; CHECK-NEXT: [[F_2:%.*]] = icmp ule i4 2, [[X]]
148-
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[F_1]], [[F_2]]
148+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, false
149149
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i4 [[Y]], [[Z]]
150-
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[T_1]]
150+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
151151
; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i4 [[X]], [[Y]]
152-
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[T_2]]
152+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
153153
; CHECK-NEXT: [[T_3:%.*]] = icmp ugt i4 [[X]], [[Z]]
154-
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[T_3]]
154+
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true
155155
; CHECK-NEXT: [[T_4:%.*]] = icmp ugt i4 2, [[A]]
156-
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[T_4]]
156+
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true
157157
; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]
158158
; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_8]]
159159
; CHECK-NEXT: [[C_9:%.*]] = icmp ule i4 [[X]], [[B:%.*]]
@@ -226,15 +226,15 @@ define i1 @test_or_chain_ule_2(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {
226226
; CHECK: exit:
227227
; CHECK-NEXT: [[F_1:%.*]] = icmp ule i4 [[X]], [[Z]]
228228
; CHECK-NEXT: [[F_2:%.*]] = icmp ule i4 2, [[X]]
229-
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[F_1]], [[F_2]]
229+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, false
230230
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i4 [[Y]], [[Z]]
231-
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[T_1]]
231+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
232232
; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i4 [[X]], [[Y]]
233-
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[T_2]]
233+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
234234
; CHECK-NEXT: [[T_3:%.*]] = icmp ugt i4 [[X]], [[Z]]
235-
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[T_3]]
235+
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true
236236
; CHECK-NEXT: [[T_4:%.*]] = icmp ugt i4 2, [[A]]
237-
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[T_4]]
237+
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true
238238
; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]
239239
; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_8]]
240240
; CHECK-NEXT: [[C_9:%.*]] = icmp ule i4 [[X]], [[B:%.*]]
@@ -308,11 +308,11 @@ define i1 @test_or_chain_with_other_conds_ule(i4 %x, i4 %y, i4 %z, i4 %a, i1 %ar
308308
; CHECK: exit:
309309
; CHECK-NEXT: [[F_1:%.*]] = icmp ule i4 [[X]], [[Z]]
310310
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i4 [[Y]], [[Z]]
311-
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[F_1]], [[T_1]]
311+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
312312
; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i4 [[X]], [[Y]]
313-
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[T_2]]
313+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
314314
; CHECK-NEXT: [[T_3:%.*]] = icmp ugt i4 [[X]], [[Z]]
315-
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[T_3]]
315+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
316316
; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]
317317
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_8]]
318318
; CHECK-NEXT: ret i1 [[RES_6]]
@@ -373,11 +373,11 @@ define i1 @test_or_chain_with_and_ule(i4 %x, i4 %y, i4 %z, i4 %a, i4 %b) {
373373
; CHECK: exit:
374374
; CHECK-NEXT: [[F_1:%.*]] = icmp ule i4 [[X]], [[Z]]
375375
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i4 [[Y]], [[Z]]
376-
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[F_1]], [[T_1]]
376+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
377377
; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i4 [[X]], [[Y]]
378-
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[T_2]]
378+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true
379379
; CHECK-NEXT: [[T_3:%.*]] = icmp ugt i4 [[X]], [[Z]]
380-
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[T_3]]
380+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true
381381
; CHECK-NEXT: [[C_8:%.*]] = icmp ule i4 [[X]], [[A]]
382382
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_8]]
383383
; CHECK-NEXT: [[C_9:%.*]] = icmp ule i4 [[X]], [[B:%.*]]

0 commit comments

Comments
 (0)