// RUN: mlir-hlo-opt -mhlo-legalize-control-flow %s -o - | FileCheck %s // CHECK-LABEL: func @while(%arg0: tensor) -> tensor { func @while(%arg0: tensor) -> tensor { //CHECK: br ^bb1(%arg0 : tensor) //CHECK: ^bb1([[VAL0:%.+]]: tensor): //CHECK: [[VAL1:%.+]] = "mhlo.compare"([[VAL0]], [[VAL0]]) //CHECK: [[VAL2:%.+]] = tensor.extract [[VAL1]][] : tensor //CHECK: cond_br [[VAL2]], ^bb2([[VAL0]] : tensor), ^bb3([[VAL0]] : tensor) //CHECK: ^bb2([[VAL3:%.+]]: tensor): //CHECK: [[VAL4:%.+]] = mhlo.add [[VAL3]], [[VAL3]] //CHECK: br ^bb1([[VAL4]] : tensor) //CHECK: ^bb3([[VAL5:%.+]]: tensor): %0 = "mhlo.while"(%arg0) ( { ^bb0(%arg1: tensor): %1 = "mhlo.compare"(%arg1, %arg1) {comparison_direction = "LT", name = "compare.2"} : (tensor, tensor) -> tensor "mhlo.return"(%1) : (tensor) -> () }, { ^bb0(%arg1: tensor): %1 = mhlo.add %arg1, %arg1 {name = "compare.0"} : tensor "mhlo.return"(%1) : (tensor) -> () }) : (tensor) -> tensor // CHECK-NEXT: return [[VAL5]] return %0 : tensor } // CHECK-LABEL: func @conditional func @conditional(%arg0: tensor) -> tensor { // CHECK: [[C0:%.+]] = constant dense<1.000000e+01> : tensor %cst = constant dense<1.000000e+01> : tensor // CHECK: [[VAL0:%.+]] = "mhlo.compare"(%arg0, [[C0]]) {comparison_direction = "LT"} : (tensor, tensor) -> tensor %0 = "mhlo.compare"(%arg0, %cst) {comparison_direction = "LT"} : (tensor, tensor) -> tensor // CHECK: [[VAL1:%.+]] = tensor.extract [[VAL0]][] : tensor // CHECK: cond_br [[VAL1]], ^bb1(%arg0 : tensor), ^bb2(%arg0 : tensor) %1 = "mhlo.if"(%0, %arg0, %arg0) ( { ^bb0(%arg1: tensor): // CHECK: ^bb1([[VAL2:%.+]]: tensor): // CHECK: [[VAL3:%.+]] = "mhlo.log"([[VAL2]]) : (tensor) -> tensor // CHECK: br ^bb3([[VAL3]] : tensor) %2 = "mhlo.log"(%arg1) : (tensor) -> tensor "mhlo.return"(%2) : (tensor) -> () }, { ^bb0(%arg1: tensor): // CHECK: ^bb2([[VAL4:%.+]]: tensor): // CHECK: [[VAL5:%.+]] = "mhlo.exponential"([[VAL4]]) : (tensor) -> tensor // CHECK: br ^bb3([[VAL5]] : tensor) %2 = "mhlo.exponential"(%arg1) : (tensor) -> tensor "mhlo.return"(%2) : (tensor) -> () }) : (tensor, tensor, tensor) -> tensor // CHECK: ^bb3([[VAL6:%.+]]: tensor): // CHECK: return [[VAL6]] : tensor return %1 : tensor } // CHECK-LABEL: func @while_with_multiple_blocks_in_body(%arg0: tensor) -> tensor { func @while_with_multiple_blocks_in_body(%arg0: tensor) -> tensor { // CHECK: br ^[[COND_ENTRY:.+]](%arg0 : tensor) // CHECK: ^[[COND_ENTRY]](%0: tensor): // CHECK: %1 = "mhlo.compare"(%0, %0) {comparison_direction = "LT"} : (tensor, tensor) -> tensor // CHECK: %2 = tensor.extract %1[] : tensor // CHECK: cond_br %2, ^[[BODY_ENTRY:.+]](%0 : tensor), ^[[EXIT:.+]](%0 : tensor) // CHECK: ^[[BODY_ENTRY]](%3: tensor): // CHECK: br ^[[BODY_SUCC:.+]](%3 : tensor) // CHECK: ^[[BODY_SUCC]](%4: tensor): // CHECK: %5 = mhlo.add %4, %4 : tensor // CHECK: br ^[[COND_ENTRY]](%5 : tensor) // CHECK: ^[[EXIT]](%6: tensor): // CHECK: return %6 : tensor // CHECK: } %0 = "mhlo.while"(%arg0) ( { ^cond_entry(%arg1: tensor): %1 = "mhlo.compare"(%arg1, %arg1) {comparison_direction = "LT"} : (tensor, tensor) -> tensor "mhlo.return"(%1) : (tensor) -> () }, { ^body_entry(%arg1: tensor): br ^body_succ(%arg1: tensor) ^body_succ(%0: tensor): %1 = mhlo.add %0, %0 : tensor "mhlo.return"(%1) : (tensor) -> () }) : (tensor) -> tensor return %0 : tensor } // CHECK-LABEL: func @while_with_multiple_blocks_in_cond(%arg0: tensor) -> tensor { func @while_with_multiple_blocks_in_cond(%arg0: tensor) -> tensor { // CHECK: br ^[[COND_ENTRY:.+]](%arg0 : tensor) // CHECK: ^[[COND_ENTRY]](%0: tensor): // CHECK: br ^[[COND_SUCC:.+]](%0 : tensor) // CHECK: ^[[COND_SUCC]](%1: tensor): // CHECK: %2 = "mhlo.compare"(%1, %1) {comparison_direction = "LT"} : (tensor, tensor) -> tensor // CHECK: %3 = tensor.extract %2[] : tensor // CHECK: cond_br %3, ^[[BODY_ENTRY:.+]](%0 : tensor), ^[[EXIT:.+]](%0 : tensor) // CHECK: ^[[BODY_ENTRY]](%4: tensor): // CHECK: br ^[[COND_ENTRY]](%4 : tensor) // CHECK: ^[[EXIT]](%5: tensor): // CHECK: return %5 : tensor // CHECK: } %0 = "mhlo.while"(%arg0) ( { ^cond_entry(%arg1: tensor): br ^cond_succ(%arg1: tensor) ^cond_succ(%0: tensor): %1 = "mhlo.compare"(%0, %0) {comparison_direction = "LT"} : (tensor, tensor) -> tensor "mhlo.return"(%1) : (tensor) -> () }, { ^body_entry(%arg1: tensor): "mhlo.return"(%arg1) : (tensor) -> () }) : (tensor) -> tensor return %0 : tensor } // CHECK-LABEL: func @conditional_with_multiple_blocks(%arg0: tensor, %arg1: tensor, %arg2: tensor) -> tensor { func @conditional_with_multiple_blocks(%arg0: tensor, %arg1: tensor, %pred: tensor) -> tensor { // CHECK: %0 = tensor.extract %arg2[] : tensor // CHECK: cond_br %0, ^[[THEN_ENTRY:.+]](%arg0 : tensor), ^[[ELSE_ENTRY:.+]](%arg1 : tensor) // CHECK: ^[[THEN_ENTRY]](%1: tensor): // CHECK: br ^[[THEN_SUCC:.+]](%1 : tensor) // CHECK: ^[[THEN_SUCC]](%2: tensor): // CHECK: %3 = "mhlo.log"(%2) : (tensor) -> tensor // CHECK: br ^[[EXIT:.+]](%3 : tensor) // CHECK: ^[[ELSE_ENTRY]](%4: tensor): // CHECK: %5 = "mhlo.exponential"(%4) : (tensor) -> tensor // CHECK: br ^[[EXIT]](%5 : tensor) // CHECK: ^[[EXIT]](%6: tensor): // CHECK: return %6 : tensor // CHECK: } %1 = "mhlo.if"(%pred, %arg0, %arg1) ( { ^then_entry(%arg2: tensor): br ^then_succ(%arg2: tensor) ^then_succ(%0: tensor): %2 = "mhlo.log"(%0) : (tensor) -> tensor "mhlo.return"(%2) : (tensor) -> () }, { ^else_entry(%arg2: tensor): %2 = "mhlo.exponential"(%arg2) : (tensor) -> tensor "mhlo.return"(%2) : (tensor) -> () }) : (tensor, tensor, tensor) -> tensor return %1 : tensor }