Files
clang-p2996/llvm/test/Transforms/InstCombine/recurrence.ll
Philip Reames ebc61f9d3c [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)
2021-03-08 09:21:38 -08:00

166 lines
4.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -instcombine -S < %s | FileCheck %s
define i64 @test_or(i64 %a) {
; CHECK-LABEL: @test_or(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], 15
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = or i64 %iv, 15
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_or2(i64 %a, i64 %b) {
; CHECK-LABEL: @test_or2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = or i64 %iv, %b
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_or3(i64 %a, i64 %b) {
; CHECK-LABEL: @test_or3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = or i64 %b, %iv
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_or4(i64 %a, i64* %p) {
; CHECK-LABEL: @test_or4(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[STEP:%.*]] = load volatile i64, i64* [[P:%.*]], align 4
; CHECK-NEXT: [[IV_NEXT]] = or i64 [[IV]], [[STEP]]
; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%step = load volatile i64, i64* %p
%iv.next = or i64 %iv, %step
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_and(i64 %a) {
; CHECK-LABEL: @test_and(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[A:%.*]], 15
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = and i64 %iv, 15
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_and2(i64 %a, i64 %b) {
; CHECK-LABEL: @test_and2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = and i64 %iv, %b
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_and3(i64 %a, i64 %b) {
; CHECK-LABEL: @test_and3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: tail call void @use(i64 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%iv.next = and i64 %b, %iv
tail call void @use(i64 %iv.next)
br label %loop
}
define i64 @test_and4(i64 %a, i64* %p) {
; CHECK-LABEL: @test_and4(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[STEP:%.*]] = load volatile i64, i64* [[P:%.*]], align 4
; CHECK-NEXT: [[IV_NEXT]] = and i64 [[IV]], [[STEP]]
; CHECK-NEXT: tail call void @use(i64 [[IV_NEXT]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ %a, %entry ], [ %iv.next, %loop ]
%step = load volatile i64, i64* %p
%iv.next = and i64 %iv, %step
tail call void @use(i64 %iv.next)
br label %loop
}
declare void @use(i64)