[llvm] 6792e26 - Reapply "Look through invertible recurrences in isKnownNonEqual"
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 20 12:48:06 PDT 2021
Author: Philip Reames
Date: 2021-04-20T12:47:59-07:00
New Revision: 6792e26c0d0f2260f1e12693382e184f5ea1966f
URL: https://github.com/llvm/llvm-project/commit/6792e26c0d0f2260f1e12693382e184f5ea1966f
DIFF: https://github.com/llvm/llvm-project/commit/6792e26c0d0f2260f1e12693382e184f5ea1966f.diff
LOG: Reapply "Look through invertible recurrences in isKnownNonEqual"
I'd reverted this in commit 3b6acb179708ea2f3caf95ace0f134fcbc460333 due to buildbot failures. This patch contains the fix for said issue. I'd forgotten to handle the case where two phis in the same block have different operand order. We canonicalize away from this, but it's still valid IR. The tests included in this change (as opposed to simply having test output changed), crashed without the fix.
Original commit message follows...
This extends the phi handling in isKnownNonEqual with a special case based on invertible recurrences. If we can prove the recurrence is invertible (which many common ones are), we can recurse through the start operands of the recurrence skipping the phi cycle.
(Side note: Instcombine currently does not push back through these cases. I will implement that in a follow up change w/separate review.)
Differential Revision: https://reviews.llvm.org/D99912
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Analysis/ValueTracking/known-non-equal.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 46aa84f72aaf..7b2cd163b6ee 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2580,6 +2580,35 @@ static Optional<unsigned> getInvertibleOperand(const Operator *Op1,
if (Op1->getOperand(0)->getType() == Op2->getOperand(0)->getType())
return 0;
break;
+ case Instruction::PHI: {
+ const PHINode *PN1 = cast<PHINode>(Op1);
+ const PHINode *PN2 = cast<PHINode>(Op2);
+
+ // If PN1 and PN2 are both recurrences, can we prove the entire recurrences
+ // are a single invertible function of the start values? Note that repeated
+ // application of an invertible function is also invertible
+ BinaryOperator *BO1 = nullptr;
+ Value *Start1 = nullptr, *Step1 = nullptr;
+ BinaryOperator *BO2 = nullptr;
+ Value *Start2 = nullptr, *Step2 = nullptr;
+ if (PN1->getParent() != PN2->getParent() ||
+ !matchSimpleRecurrence(PN1, BO1, Start1, Step1) ||
+ !matchSimpleRecurrence(PN2, BO2, Start2, Step2))
+ break;
+
+ Optional<unsigned> Idx = getInvertibleOperand(cast<Operator>(BO1),
+ cast<Operator>(BO2));
+ if (!Idx || *Idx != 0)
+ break;
+ assert(BO1->getOperand(*Idx) == PN1 && BO2->getOperand(*Idx) == PN2);
+
+ // Phi operands might not be in the same order. TODO: generalize
+ // interface to return pair of operands.
+ if (PN1->getOperand(0) == BO1 && PN2->getOperand(0) == BO2)
+ return 1;
+ if (PN1->getOperand(1) == BO1 && PN2->getOperand(1) == BO2)
+ return 0;
+ }
}
return None;
}
diff --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
index 257a0a255af3..4e3a0ecd61e3 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -598,8 +598,7 @@ define i1 @recurrence_add_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
@@ -775,6 +774,42 @@ define i1 @recurrence_add_neq_phi_order(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %B = add i8 %A, 1
+ br label %loop
+loop:
+ %iv = phi i64 [%iv.next, %loop], [0, %entry]
+ %A.iv = phi i8 [%A.iv.next, %loop], [%A, %entry]
+ %B.iv = phi i8 [%B.iv.next, %loop], [%B, %entry]
+ %iv.next = add i64 %iv, 1
+ %A.iv.next = add i8 %A.iv, 1
+ %B.iv.next = add i8 %B.iv, 1
+ %cmp = icmp ne i64 %iv.next, 10
+ br i1 %cmp, label %loop, label %exit
+exit:
+ %res = icmp eq i8 %A.iv, %B.iv
+ ret i1 %res
+}
+
+; Demonstrate case where phi operand orders
diff er and thus
+; there's no single operand index to recurse through
+define i1 @recurrence_add_phi_
diff erent_order1(i8 %A) {
+; CHECK-LABEL: @recurrence_add_phi_
diff erent_order1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[B:%.*]] = add i8 [[A:%.*]], 1
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[B_IV:%.*]] = phi i8 [ [[B_IV_NEXT:%.*]], [[LOOP]] ], [ [[B]], [[ENTRY]] ]
+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT: [[A_IV_NEXT]] = add i8 [[A_IV]], 1
+; CHECK-NEXT: [[B_IV_NEXT]] = add i8 [[B_IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
+; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
; CHECK-NEXT: ret i1 [[RES]]
;
@@ -783,7 +818,7 @@ entry:
br label %loop
loop:
%iv = phi i64 [%iv.next, %loop], [0, %entry]
- %A.iv = phi i8 [%A.iv.next, %loop], [%A, %entry]
+ %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
%B.iv = phi i8 [%B.iv.next, %loop], [%B, %entry]
%iv.next = add i64 %iv, 1
%A.iv.next = add i8 %A.iv, 1
@@ -795,6 +830,41 @@ exit:
ret i1 %res
}
+define i1 @recurrence_add_phi_
diff erent_order2(i8 %A) {
+; CHECK-LABEL: @recurrence_add_phi_
diff erent_order2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[B:%.*]] = add i8 [[A:%.*]], 1
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[A_IV:%.*]] = phi i8 [ [[A_IV_NEXT:%.*]], [[LOOP]] ], [ [[A]], [[ENTRY]] ]
+; CHECK-NEXT: [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT: [[A_IV_NEXT]] = add i8 [[A_IV]], 1
+; CHECK-NEXT: [[B_IV_NEXT]] = add i8 [[B_IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
+; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
+; CHECK-NEXT: ret i1 [[RES]]
+;
+entry:
+ %B = add i8 %A, 1
+ br label %loop
+loop:
+ %iv = phi i64 [%iv.next, %loop], [0, %entry]
+ %A.iv = phi i8 [%A.iv.next, %loop], [%A, %entry]
+ %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
+ %iv.next = add i64 %iv, 1
+ %A.iv.next = add i8 %A.iv, 1
+ %B.iv.next = add i8 %B.iv, 1
+ %cmp = icmp ne i64 %iv.next, 10
+ br i1 %cmp, label %loop, label %exit
+exit:
+ %res = icmp eq i8 %A.iv, %B.iv
+ ret i1 %res
+}
+
define i1 @recurrence_sub_neq(i8 %A) {
; CHECK-LABEL: @recurrence_sub_neq(
; CHECK-NEXT: entry:
@@ -810,8 +880,7 @@ define i1 @recurrence_sub_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
@@ -912,8 +981,7 @@ define i1 @recurrence_mul_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
@@ -1049,8 +1117,7 @@ define i1 @recurrence_shl_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
@@ -1186,8 +1253,7 @@ define i1 @recurrence_lshr_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
@@ -1323,8 +1389,7 @@ define i1 @recurrence_ashr_neq(i8 %A) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
-; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 false
;
entry:
%B = add i8 %A, 1
More information about the llvm-commits
mailing list