[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