diff --git a/llvm/test/Transforms/InstCombine/recurrence.ll b/llvm/test/Transforms/InstCombine/recurrence.ll new file mode 100644 index 00000000000000..82f7b3bca154c7 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/recurrence.ll @@ -0,0 +1,171 @@ +; 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: [[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: 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: [[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: 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: [[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: 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: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[IV_NEXT]] = and i64 [[IV]], 15 +; 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 ] + %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: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[IV_NEXT]] = and i64 [[IV]], [[B:%.*]] +; 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 ] + %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: [[IV:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[IV_NEXT]] = and i64 [[IV]], [[B:%.*]] +; 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 ] + %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)