[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)
This commit is contained in:
Philip Reames 2021-03-08 09:17:11 -08:00
parent 239a618180
commit ebc61f9d3c
2 changed files with 12 additions and 9 deletions

View File

@ -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;
}

View File

@ -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: