diff --git a/flang/lib/Optimizer/Transforms/PolymorphicOpConversion.cpp b/flang/lib/Optimizer/Transforms/PolymorphicOpConversion.cpp index ab9f1d768b039..f5d0602c270cc 100644 --- a/flang/lib/Optimizer/Transforms/PolymorphicOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/PolymorphicOpConversion.cpp @@ -340,7 +340,8 @@ mlir::LogicalResult SelectTypeConv::matchAndRewrite( std::optional destOps = selectType.getSuccessorOperands(operands, idx); if (typeGuards[idx].dyn_cast()) - rewriter.replaceOpWithNewOp(selectType, dest); + rewriter.replaceOpWithNewOp( + selectType, dest, destOps.value_or(mlir::ValueRange{})); else if (mlir::failed(genTypeLadderStep(loc, selector, typeGuards[idx], dest, destOps, mod, rewriter, kindMap))) diff --git a/flang/test/Lower/select-type-2.fir b/flang/test/Lower/select-type-2.fir new file mode 100644 index 0000000000000..011a32b5def06 --- /dev/null +++ b/flang/test/Lower/select-type-2.fir @@ -0,0 +1,105 @@ +// RUN: fir-opt --fir-polymorphic-op %s | FileCheck %s + +// Test that cf.br for the default select case passes the blocks argument +// as expected. + +// Original code: +//subroutine test() +// interface +// function fstar() +// class(*),pointer :: fstar +// end function fstar +// subroutine foo(x) +// class(*) :: x +// end subroutine foo +// end interface +// +// select type(y=>fstar()) +// type is (integer) +// y = 777 +// class default +// call foo(y) +// stop 'fail type' +// end select +// +// select type(y=>fstar()) +// type is (integer) +// y = 23 +// class default +// call foo(y) +// stop 'fail type' +// end select +//end subroutine test + +// CHECK-LABEL: func.func @_QPtest() { +// CHECK: %[[VAL_0:.*]] = arith.constant 23 : i32 +// CHECK: %[[VAL_1:.*]] = arith.constant false +// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 777 : i32 +// CHECK: %[[VAL_4:.*]] = fir.alloca !fir.class> {bindc_name = ".result"} +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.class> {bindc_name = ".result"} +// CHECK: %[[VAL_6:.*]] = fir.call @_QPfstar() fastmath : () -> !fir.class> +// CHECK: fir.save_result %[[VAL_6]] to %[[VAL_5]] : !fir.class>, !fir.ref>> +// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]] : !fir.ref>> +// CHECK: %[[VAL_8:.*]] = arith.constant 9 : i8 +// CHECK: %[[VAL_9:.*]] = fir.box_typecode %[[VAL_7]] : (!fir.class>) -> i8 +// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_8]] : i8 +// CHECK: cf.cond_br %[[VAL_10]], ^bb2, ^bb1 +// CHECK: ^bb1: +// CHECK: cf.br ^bb3(%[[VAL_7]] : !fir.class>) +// CHECK: ^bb2: +// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_7]] : (!fir.class>) -> !fir.ptr +// CHECK: fir.store %[[VAL_3]] to %[[VAL_11]] : !fir.ptr +// CHECK: %[[VAL_12:.*]] = fir.call @_QPfstar() fastmath : () -> !fir.class> +// CHECK: fir.save_result %[[VAL_12]] to %[[VAL_4]] : !fir.class>, !fir.ref>> +// CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_4]] : !fir.ref>> +// CHECK: %[[VAL_14:.*]] = arith.constant 9 : i8 +// CHECK: %[[VAL_15:.*]] = fir.box_typecode %[[VAL_13]] : (!fir.class>) -> i8 +// CHECK: %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_15]], %[[VAL_14]] : i8 +// CHECK: cf.cond_br %[[VAL_16]], ^bb5, ^bb4 +// CHECK: ^bb3(%[[VAL_17:.*]]: !fir.class>): +// CHECK: %[[VAL_18:.*]] = fir.rebox %[[VAL_17]] : (!fir.class>) -> !fir.class +// CHECK: fir.call @_QPfoo(%[[VAL_18]]) fastmath : (!fir.class) -> () +// CHECK: %[[VAL_19:.*]] = fir.address_of(@_QQcl.6661696C2074797065) : !fir.ref> +// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_2]] : (index) -> i64 +// CHECK: %[[VAL_22:.*]] = fir.call @_FortranAStopStatementText(%[[VAL_20]], %[[VAL_21]], %[[VAL_1]], %[[VAL_1]]) fastmath : (!fir.ref, i64, i1, i1) -> none +// CHECK: fir.unreachable +// CHECK: ^bb4: +// CHECK: cf.br ^bb3(%[[VAL_13]] : !fir.class>) +// CHECK: ^bb5: +// CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_13]] : (!fir.class>) -> !fir.ptr +// CHECK: fir.store %[[VAL_0]] to %[[VAL_23]] : !fir.ptr +// CHECK: return +// CHECK: } +func.func @_QPtest() { + %c23_i32 = arith.constant 23 : i32 + %false = arith.constant false + %c9 = arith.constant 9 : index + %c777_i32 = arith.constant 777 : i32 + %0 = fir.alloca !fir.class> {bindc_name = ".result"} + %1 = fir.alloca !fir.class> {bindc_name = ".result"} + %2 = fir.call @_QPfstar() fastmath : () -> !fir.class> + fir.save_result %2 to %1 : !fir.class>, !fir.ref>> + %3 = fir.load %1 : !fir.ref>> + fir.select_type %3 : !fir.class> [#fir.type_is, ^bb1, unit, ^bb2(%3 : !fir.class>)] +^bb1: // pred: ^bb0 + %4 = fir.box_addr %3 : (!fir.class>) -> !fir.ptr + fir.store %c777_i32 to %4 : !fir.ptr + %5 = fir.call @_QPfstar() fastmath : () -> !fir.class> + fir.save_result %5 to %0 : !fir.class>, !fir.ref>> + %6 = fir.load %0 : !fir.ref>> + fir.select_type %6 : !fir.class> [#fir.type_is, ^bb3, unit, ^bb2(%6 : !fir.class>)] +^bb2(%7: !fir.class>): // 2 preds: ^bb0, ^bb1 + %8 = fir.rebox %7 : (!fir.class>) -> !fir.class + fir.call @_QPfoo(%8) fastmath : (!fir.class) -> () + %9 = fir.address_of(@_QQcl.6661696C2074797065) : !fir.ref> + %10 = fir.convert %9 : (!fir.ref>) -> !fir.ref + %11 = fir.convert %c9 : (index) -> i64 + %12 = fir.call @_FortranAStopStatementText(%10, %11, %false, %false) fastmath : (!fir.ref, i64, i1, i1) -> none + fir.unreachable +^bb3: // pred: ^bb1 + %13 = fir.box_addr %6 : (!fir.class>) -> !fir.ptr + fir.store %c23_i32 to %13 : !fir.ptr + return +}