diff --git a/flang/lib/Optimizer/Transforms/LoopVersioning.cpp b/flang/lib/Optimizer/Transforms/LoopVersioning.cpp index 48e42bdab5c0e..bca70a0a0d322 100644 --- a/flang/lib/Optimizer/Transforms/LoopVersioning.cpp +++ b/flang/lib/Optimizer/Transforms/LoopVersioning.cpp @@ -144,16 +144,6 @@ struct ArgsUsageInLoop { }; } // namespace -/// @c replaceOuterUses - replace uses outside of @c op with result of @c -/// outerOp -static void replaceOuterUses(mlir::Operation *op, mlir::Operation *outerOp) { - const mlir::Operation *outerParent = outerOp->getParentOp(); - op->replaceUsesWithIf(outerOp, [&](mlir::OpOperand &operand) { - mlir::Operation *owner = operand.getOwner(); - return outerParent == owner->getParentOp(); - }); -} - static fir::SequenceType getAsSequenceType(mlir::Value *v) { mlir::Type argTy = fir::unwrapPassByRefType(fir::unwrapRefType(v->getType())); return argTy.dyn_cast(); @@ -538,7 +528,7 @@ void LoopVersioningPass::runOnOperation() { // Add the original loop in the else-side of the if operation. builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); - replaceOuterUses(op.op, ifOp); + op.op->replaceAllUsesWith(ifOp); op.op->remove(); builder.insert(op.op); // Rely on "cloned loop has results, so original loop also has results". diff --git a/flang/test/Transforms/loop-versioning.fir b/flang/test/Transforms/loop-versioning.fir index 6313bc2ac36a7..d1ad1510b0e89 100644 --- a/flang/test/Transforms/loop-versioning.fir +++ b/flang/test/Transforms/loop-versioning.fir @@ -263,7 +263,7 @@ func.func @sum1dfixed(%arg0: !fir.ref> {fir.bindc_name = "a"}, // CHECK-SAME: %[[N1:.*]]: !fir.ref {{.*}}, // CHECK-SAME: %[[M1:.*]]: !fir.ref {{.*}}) { // CHECK: fir.do_loop -// CHECL: %[[FOUR:.*]] = arith.constant 4 : index +// CHECK: %[[FOUR:.*]] = arith.constant 4 : index // CHECK: %[[COMP:.*]] = arith.cmpi {{.*}}, %[[FOUR]] // CHECK: fir.if %[[COMP]] -> {{.*}} { // CHECK: %[[CONV:.*]] = fir.convert %[[B]] : @@ -1478,4 +1478,83 @@ func.func @sum1drebox(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-NOT: fir.if +// Check for a use in a different block (%12 = do_loop is used inside the if %14 block) +func.func @minloc(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.box> {fir.bindc_name = "mask"}) -> f32 { + %c2147483647_i32 = arith.constant 2147483647 : i32 + %c1_i32 = arith.constant 1 : i32 + %c0 = arith.constant 0 : index + %c0_i32 = arith.constant 0 : i32 + %c5_i32 = arith.constant 5 : i32 + %c5 = arith.constant 5 : index + %c1 = arith.constant 1 : index + %0 = fir.alloca i32 + %1 = fir.alloca !fir.array<1xi32> + %2 = fir.declare %arg1 {uniq_name = "_QFtestEmask"} : (!fir.box>) -> !fir.box> + %3 = fir.rebox %2 : (!fir.box>) -> !fir.box> + %4 = fir.alloca f32 {bindc_name = "test", uniq_name = "_QFtestEtest"} + %5 = fir.declare %4 {uniq_name = "_QFtestEtest"} : (!fir.ref) -> !fir.ref + %6 = fir.declare %arg0 {uniq_name = "_QFtestEx"} : (!fir.box>) -> !fir.box> + %7 = fir.rebox %6 : (!fir.box>) -> !fir.box> + %8 = fir.shape %c1 : (index) -> !fir.shape<1> + %9 = fir.array_coor %1(%8) %c1 : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + fir.store %c0_i32 to %9 : !fir.ref + fir.store %c0_i32 to %0 : !fir.ref + %10:3 = fir.box_dims %7, %c0 : (!fir.box>, index) -> (index, index, index) + %11 = arith.subi %10#1, %c1 : index + %12 = fir.do_loop %arg2 = %c0 to %11 step %c1 iter_args(%arg3 = %c2147483647_i32) -> (i32) { + %18 = arith.addi %arg2, %c1 : index + %19 = fir.array_coor %3 %18 : (!fir.box>, index) -> !fir.ref + %20 = fir.load %19 : !fir.ref + %21 = arith.cmpi sge, %20, %c5_i32 : i32 + %22 = fir.if %21 -> (i32) { + fir.store %c1_i32 to %0 : !fir.ref + %23 = arith.subi %10#0, %c1 : index + %24 = arith.addi %18, %23 : index + %25 = fir.array_coor %7 %24 : (!fir.box>, index) -> !fir.ref + %26 = fir.load %25 : !fir.ref + %27 = arith.cmpi slt, %26, %arg3 : i32 + %28 = fir.if %27 -> (i32) { + %29 = fir.convert %18 : (index) -> i32 + fir.store %29 to %9 : !fir.ref + fir.result %26 : i32 + } else { + fir.result %arg3 : i32 + } + fir.result %28 : i32 + } else { + fir.result %arg3 : i32 + } + fir.result %22 : i32 + } + %13 = fir.load %0 : !fir.ref + %14 = arith.cmpi eq, %13, %c1_i32 : i32 + fir.if %14 { + %18 = arith.cmpi eq, %12, %c2147483647_i32 : i32 + fir.if %18 { + %19 = fir.array_coor %1(%8) %c0 : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + fir.store %c1_i32 to %19 : !fir.ref + } + } + %15 = fir.slice %c5, %c5, %c1 : (index, index, index) -> !fir.slice<1> + %16 = fir.rebox %7 [%15] : (!fir.box>, !fir.slice<1>) -> !fir.box> + fir.do_loop %arg2 = %c1 to %c1 step %c1 unordered { + %18 = fir.array_coor %1(%8) %arg2 : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref + %19 = fir.load %18 : !fir.ref + %20 = fir.array_coor %16 %arg2 : (!fir.box>, index) -> !fir.ref + fir.store %19 to %20 : !fir.ref + } + %17 = fir.load %5 : !fir.ref + return %17 : f32 +} +// CHECK-LABEL: func @minloc +// CHECK: %[[V17:.*]] = fir.if %{{.*}} -> (i32) { +// CHECK: %[[V27:.*]] = fir.do_loop +// CHECK: fir.result %[[V27]] : i32 +// CHECK: } else { +// CHECK: %[[V23:.*]] = fir.do_loop +// CHECK: fir.result %[[V23]] : i32 +// CHECK: fir.if %{{.*}} { +// CHECK: {{.*}} = arith.cmpi eq, %[[V17]], %c2147483647_i32 + + } // End module