[llvm] ebc61f9 - [instcombine] Collapse trivial or recurrences
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 8 09:21:46 PST 2021
Author: Philip Reames
Date: 2021-03-08T09:21:38-08:00
New Revision: ebc61f9d3caaf9683be6af91c33ef029b67b9ff8
URL: https://github.com/llvm/llvm-project/commit/ebc61f9d3caaf9683be6af91c33ef029b67b9ff8
DIFF: https://github.com/llvm/llvm-project/commit/ebc61f9d3caaf9683be6af91c33ef029b67b9ff8.diff
LOG: [instcombine] Collapse trivial or recurrences
If we have a recurrence of the form <Start, Or, Step> we know that the value taken by the recurrence stabilizes on the first iteration (provided step is loop invariant). We can exploit that fact to remove the loop carried dependence in the recurrence.
Differential Revision: https://reviews.llvm.org/D97578 (or part)
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/recurrence.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 022cccfd148d7..b9147e978deb3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2843,6 +2843,12 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
if (sinkNotIntoOtherHandOfAndOrOr(I))
return &I;
+ // An or recurrence w/loop invariant step is equivelent to (or start, step)
+ PHINode *PN = nullptr;
+ Value *Start = nullptr, *Step = nullptr;
+ if (matchSimpleRecurrence(&I, PN, Start, Step) && DT.dominates(Step, PN))
+ return replaceInstUsesWith(I, Builder.CreateOr(Start, Step));
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/recurrence.ll b/llvm/test/Transforms/InstCombine/recurrence.ll
index 0ff8fdddf9b83..6dfaca96cd9e3 100644
--- a/llvm/test/Transforms/InstCombine/recurrence.ll
+++ b/llvm/test/Transforms/InstCombine/recurrence.ll
@@ -6,9 +6,8 @@ define i64 @test_or(i64 %a) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[IV_NEXT]] = or i64 [[IV]], 15
-; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
+; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], 15
+; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
@@ -27,9 +26,8 @@ define i64 @test_or2(i64 %a, i64 %b) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[IV_NEXT]] = or i64 [[IV]], [[B:%.*]]
-; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
+; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
@@ -47,9 +45,8 @@ define i64 @test_or3(i64 %a, i64 %b) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[IV_NEXT]] = or i64 [[IV]], [[B:%.*]]
-; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
+; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
More information about the llvm-commits
mailing list