Skip to content

Commit cddc2c3

Browse files
committed
[ConstraintElim] Address review comments. NFC.
1 parent a90be3a commit cddc2c3

File tree

3 files changed

+191
-38
lines changed

3 files changed

+191
-38
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,6 @@ static bool checkOrAndOpImpliedByOther(
15081508
if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
15091509
return false;
15101510

1511-
// Optimistically add fact from first condition.
15121511
unsigned OldSize = DFSInStack.size();
15131512
auto InfoRestorer = make_scope_exit([&]() {
15141513
// Remove entries again.
@@ -1518,16 +1517,18 @@ static bool checkOrAndOpImpliedByOther(
15181517
DFSInStack);
15191518
}
15201519
});
1521-
// For OR, check if the negated condition implies CmpToCheck.
15221520
bool IsOr = match(JoinOp, m_LogicalOr());
15231521
SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
1522+
// Do a traversal of the AND/OR tree to add facts from leaf compares.
15241523
while (!Worklist.empty()) {
15251524
Value *Val = Worklist.pop_back_val();
15261525
Value *LHS, *RHS;
15271526
ICmpInst::Predicate Pred;
15281527
if (match(Val, m_ICmp(Pred, m_Value(LHS), m_Value(RHS)))) {
1528+
// For OR, check if the negated condition implies CmpToCheck.
15291529
if (IsOr)
15301530
Pred = CmpInst::getInversePredicate(Pred);
1531+
// Optimistically add fact from the other compares in the AND/OR.
15311532
Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
15321533
continue;
15331534
}

llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,192 @@ entry:
497497
ret i1 %and
498498
}
499499

500+
define void @and_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
501+
; CHECK-LABEL: @and_tree_second_implies_first(
502+
; CHECK-NEXT: entry:
503+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
504+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
505+
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]
506+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
507+
; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
508+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
509+
; CHECK: if.then:
510+
; CHECK-NEXT: call void @side_effect()
511+
; CHECK-NEXT: br label [[RETURN]]
512+
; CHECK: return:
513+
; CHECK-NEXT: ret void
514+
;
515+
entry:
516+
%cmp0 = icmp sge i32 %v0, %v1
517+
%cmp1 = icmp sge i32 %v1, %v2
518+
%and1 = and i1 %cmp0, %cmp1
519+
%cmp2 = icmp slt i32 %v0, %v2
520+
%and2 = and i1 %cmp2, %and1
521+
br i1 %and2, label %if.then, label %return
522+
523+
if.then:
524+
call void @side_effect()
525+
br label %return
526+
527+
return:
528+
ret void
529+
}
530+
531+
define void @and_tree_second_implies_first_perm1(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
532+
; CHECK-LABEL: @and_tree_second_implies_first_perm1(
533+
; CHECK-NEXT: entry:
534+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
535+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
536+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
537+
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]]
538+
; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
539+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
540+
; CHECK: if.then:
541+
; CHECK-NEXT: call void @side_effect()
542+
; CHECK-NEXT: br label [[RETURN]]
543+
; CHECK: return:
544+
; CHECK-NEXT: ret void
545+
;
546+
entry:
547+
%cmp0 = icmp sge i32 %v0, %v1
548+
%cmp1 = icmp sge i32 %v1, %v2
549+
%cmp2 = icmp slt i32 %v0, %v2
550+
%and1 = and i1 %cmp2, %cmp1
551+
%and2 = and i1 %cmp0, %and1
552+
br i1 %and2, label %if.then, label %return
553+
554+
if.then:
555+
call void @side_effect()
556+
br label %return
557+
558+
return:
559+
ret void
560+
}
561+
562+
563+
define void @and_tree_second_implies_first_perm2(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
564+
; CHECK-LABEL: @and_tree_second_implies_first_perm2(
565+
; CHECK-NEXT: entry:
566+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
567+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
568+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
569+
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]]
570+
; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]]
571+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
572+
; CHECK: if.then:
573+
; CHECK-NEXT: call void @side_effect()
574+
; CHECK-NEXT: br label [[RETURN]]
575+
; CHECK: return:
576+
; CHECK-NEXT: ret void
577+
;
578+
entry:
579+
%cmp0 = icmp sge i32 %v0, %v1
580+
%cmp1 = icmp sge i32 %v1, %v2
581+
%cmp2 = icmp slt i32 %v0, %v2
582+
%and1 = and i1 %cmp0, %cmp2
583+
%and2 = and i1 %cmp1, %and1
584+
br i1 %and2, label %if.then, label %return
585+
586+
if.then:
587+
call void @side_effect()
588+
br label %return
589+
590+
return:
591+
ret void
592+
}
593+
594+
define void @logical_and_tree_second_implies_first(i32 %v0, i32 %v1, i32 %v2) {
595+
; CHECK-LABEL: @logical_and_tree_second_implies_first(
596+
; CHECK-NEXT: entry:
597+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
598+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
599+
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false
600+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
601+
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false
602+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
603+
; CHECK: if.then:
604+
; CHECK-NEXT: call void @side_effect()
605+
; CHECK-NEXT: br label [[RETURN]]
606+
; CHECK: return:
607+
; CHECK-NEXT: ret void
608+
;
609+
entry:
610+
%cmp0 = icmp sge i32 %v0, %v1
611+
%cmp1 = icmp sge i32 %v1, %v2
612+
%and1 = select i1 %cmp0, i1 %cmp1, i1 false
613+
%cmp2 = icmp slt i32 %v0, %v2
614+
%and2 = select i1 %cmp2, i1 %and1, i1 false
615+
br i1 %and2, label %if.then, label %return
616+
617+
if.then:
618+
call void @side_effect()
619+
br label %return
620+
621+
return:
622+
ret void
623+
}
624+
625+
define void @or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
626+
; CHECK-LABEL: @or_tree_second_implies_first(
627+
; CHECK-NEXT: entry:
628+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
629+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
630+
; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
631+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
632+
; CHECK-NEXT: [[AND2:%.*]] = or i1 true, [[AND1]]
633+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
634+
; CHECK: if.then:
635+
; CHECK-NEXT: call void @side_effect()
636+
; CHECK-NEXT: br label [[RETURN]]
637+
; CHECK: return:
638+
; CHECK-NEXT: ret void
639+
;
640+
entry:
641+
%cmp0 = icmp sge i32 %v0, %v1
642+
%cmp1 = icmp sge i32 %v1, %v2
643+
%and1 = or i1 %cmp0, %cmp1
644+
%cmp2 = icmp slt i32 %v0, %v2
645+
%and2 = or i1 %cmp2, %and1
646+
br i1 %and2, label %if.then, label %return
647+
648+
if.then:
649+
call void @side_effect()
650+
br label %return
651+
652+
return:
653+
ret void
654+
}
655+
656+
define void @negative_and_or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {
657+
; CHECK-LABEL: @negative_and_or_tree_second_implies_first(
658+
; CHECK-NEXT: entry:
659+
; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]
660+
; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]
661+
; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]
662+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]
663+
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]
664+
; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
665+
; CHECK: if.then:
666+
; CHECK-NEXT: call void @side_effect()
667+
; CHECK-NEXT: br label [[RETURN]]
668+
; CHECK: return:
669+
; CHECK-NEXT: ret void
670+
;
671+
entry:
672+
%cmp0 = icmp sge i32 %v0, %v1
673+
%cmp1 = icmp sge i32 %v1, %v2
674+
%and1 = or i1 %cmp0, %cmp1
675+
%cmp2 = icmp slt i32 %v0, %v2
676+
%and2 = and i1 %cmp2, %and1
677+
br i1 %and2, label %if.then, label %return
678+
679+
if.then:
680+
call void @side_effect()
681+
br label %return
682+
683+
return:
684+
ret void
685+
}
686+
687+
declare void @side_effect()
500688
declare void @no_noundef(i1 noundef)

llvm/test/Transforms/ConstraintElimination/unreachable-bb.ll

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)