| // RUN: mlir-opt %s --mlir-disable-threading -test-block-is-in-loop 2>&1 | FileCheck %s |
| |
| module { |
| // Test function with only one bb |
| func.func @simple() { |
| func.return |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0: |
| |
| // Test simple loop bb0 -> bb0 |
| func.func @loopForever() { |
| ^bb0: |
| cf.br ^bb1 |
| ^bb1: |
| cf.br ^bb1 |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb1: |
| |
| // Test bb0 -> bb1 -> bb2 -> bb1 |
| func.func @loopForever2() { |
| ^bb0: |
| cf.br ^bb1 |
| ^bb1: |
| cf.br ^bb2 |
| ^bb2: |
| cf.br ^bb1 |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb1: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb2: |
| |
| // Test conditional branch without loop |
| // bb0 -> bb1 -> {bb2, bb3} |
| func.func @noLoop(%arg0: i1) { |
| cf.br ^bb1 |
| ^bb1: |
| cf.cond_br %arg0, ^bb2, ^bb3 |
| ^bb2: |
| func.return |
| ^bb3: |
| func.return |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0(%arg0: i1) |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb1: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb2: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb3: |
| |
| // test multiple loops |
| // bb0 -> bb1 -> bb2 -> bb3 { -> bb2} -> bb4 { -> bb1 } -> bb5 |
| func.func @multipleLoops(%arg0: i1, %arg1: i1) { |
| cf.br ^bb1 |
| ^bb1: |
| cf.br ^bb2 |
| ^bb2: |
| cf.br ^bb3 |
| ^bb3: |
| cf.cond_br %arg0, ^bb4, ^bb2 |
| ^bb4: |
| cf.cond_br %arg1, ^bb1, ^bb5 |
| ^bb5: |
| return |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0(%arg0: i1, %arg1: i1) |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb1: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb2: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb3: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb4: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb5: |
| |
| // test derived from real Flang output |
| func.func @_QPblockTest0(%arg0: i1, %arg1: i1) { |
| cf.br ^bb1 |
| ^bb1: // 2 preds: ^bb0, ^bb4 |
| cf.cond_br %arg0, ^bb2, ^bb5 |
| ^bb2: // pred: ^bb1 |
| cf.cond_br %arg1, ^bb3, ^bb4 |
| ^bb3: // pred: ^bb2 |
| return |
| ^bb4: // pred: ^bb2 |
| cf.br ^bb1 |
| ^bb5: // pred: ^bb1 |
| return |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0(%arg0: i1, %arg1: i1) |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb1: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb2: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb3: |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb4: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb5: |
| |
| // check nested blocks |
| func.func @check_alloc_in_loop(%counter : i64) { |
| cf.br ^bb1(%counter: i64) |
| ^bb1(%lv : i64): |
| %cm1 = arith.constant -1 : i64 |
| %rem = arith.addi %lv, %cm1 : i64 |
| %zero = arith.constant 0 : i64 |
| %p = arith.cmpi eq, %rem, %zero : i64 |
| cf.cond_br %p, ^bb3, ^bb2 |
| ^bb2: |
| scf.execute_region -> () { |
| %c1 = arith.constant 1 : i64 |
| scf.yield |
| } |
| cf.br ^bb1(%rem: i64) |
| ^bb3: |
| return |
| } |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb0(%arg0: i64): |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb1(%0: i64) |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb0: |
| // CHECK-NEXT: %c1_i64 |
| // CHECK: Block is in a loop |
| // CHECK-NEXT: ^bb2: |
| // CHECK: Block is not in a loop |
| // CHECK-NEXT: ^bb3: |
| } |