Skip to content

Commit 17962c5

Browse files
committed
Fix handling of !fir.boxchar types
1 parent 16cc35d commit 17962c5

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -487,23 +487,37 @@ class FunctionFilteringPass
487487
}
488488

489489
// We don't actually need the proper initialization, but rather just
490-
// maintain the basic form of these operands. We create 1-bit placeholder
491-
// allocas that we "typecast" to the expected type and replace all uses.
492-
// Using fir.undefined here instead is not possible because these variables
493-
// cannot be constants, as that would trigger different codegen for target
494-
// regions.
490+
// maintain the basic form of these operands. Generally, we create 1-bit
491+
// placeholder allocas that we "typecast" to the expected type and replace
492+
// all uses. Using fir.undefined here instead is not possible because these
493+
// variables cannot be constants, as that would trigger different codegen
494+
// for target regions.
495495
applyChildRewrites(region, childValRewrites, rewriteValues,
496496
parentValRewrites);
497497
for (Value value : rewriteValues) {
498498
Location loc = value.getLoc();
499499
Value rewriteValue;
500-
// If it's defined by fir.address_of, then we need to keep that op as
501-
// well because it might be pointing to a 'declare target' global.
502-
// Constants can also trigger different codegen paths, so we keep them as
503-
// well.
504500
if (isa_and_present<arith::ConstantOp, fir::AddrOfOp>(
505501
value.getDefiningOp())) {
502+
// If it's defined by fir.address_of, then we need to keep that op as
503+
// well because it might be pointing to a 'declare target' global.
504+
// Constants can also trigger different codegen paths, so we keep them
505+
// as well.
506506
rewriteValue = builder.clone(*value.getDefiningOp())->getResult(0);
507+
} else if (auto boxCharType =
508+
dyn_cast<fir::BoxCharType>(value.getType())) {
509+
// !fir.boxchar types cannot be directly obtained by converting a
510+
// !fir.ref<i1>, as they aren't reference types. Since they can appear
511+
// representing some `target firstprivate` clauses, we need to create
512+
// a special case here based on creating a placeholder fir.emboxchar op.
513+
MLIRContext *ctx = &getContext();
514+
fir::KindTy kind = boxCharType.getKind();
515+
auto placeholder = builder.create<fir::AllocaOp>(
516+
loc, fir::CharacterType::getSingleton(ctx, kind));
517+
auto one = builder.create<arith::ConstantOp>(
518+
loc, builder.getI32Type(), builder.getI32IntegerAttr(1));
519+
rewriteValue = builder.create<fir::EmboxCharOp>(loc, boxCharType,
520+
placeholder, one);
507521
} else {
508522
Value placeholder =
509523
builder.create<fir::AllocaOp>(loc, builder.getI1Type());

flang/test/Transforms/OpenMP/function-filtering-host-ops.mlir

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,23 @@ module attributes {omp.is_target_device = true} {
473473
return
474474
}
475475

476+
// CHECK-LABEL: func.func @assumed_length
477+
// CHECK-SAME: (%[[ARG:.*]]: !fir.boxchar<1>)
478+
func.func @assumed_length(%arg: !fir.boxchar<1>) {
479+
// CHECK-NEXT: %[[PLACEHOLDER:.*]] = fir.alloca !fir.char<1>
480+
// CHECK-NEXT: %[[ONE:.*]] = arith.constant 1 : i32
481+
// CHECK-NEXT: %[[EMBOXCHAR:.*]] = fir.emboxchar %[[PLACEHOLDER]], %[[ONE]] : (!fir.ref<!fir.char<1>>, i32) -> !fir.boxchar<1>
482+
// CHECK-NEXT: omp.target private(@boxchar_firstprivatizer %[[EMBOXCHAR]] -> %{{.*}} [map_idx=0] : !fir.boxchar<1>)
483+
%0 = fir.alloca !fir.boxchar<1>
484+
%1 = fir.dummy_scope : !fir.dscope
485+
%2:2 = fir.unboxchar %arg : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
486+
%3:2 = hlfir.declare %2#0 typeparams %2#1 dummy_scope %1 {uniq_name = "arg"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
487+
omp.target private(@boxchar_firstprivatizer %3#0 -> %arg3 [map_idx=0] : !fir.boxchar<1>) {
488+
omp.terminator
489+
}
490+
return
491+
}
492+
476493
func.func private @foo() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>}
477494
fir.global internal @global_scalar constant : i32 {
478495
%0 = arith.constant 10 : i32
@@ -495,4 +512,21 @@ module attributes {omp.is_target_device = true} {
495512
%1 = arith.addi %arg0, %arg1 : i32
496513
omp.yield (%1 : i32)
497514
}
515+
omp.private {type = firstprivate} @boxchar_firstprivatizer : !fir.boxchar<1> init {
516+
^bb0(%arg0: !fir.boxchar<1>, %arg1: !fir.boxchar<1>):
517+
%0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
518+
%1 = fir.allocmem !fir.char<1,?>(%0#1 : index) {bindc_name = "", uniq_name = ""}
519+
%2 = fir.emboxchar %1, %0#1 : (!fir.heap<!fir.char<1,?>>, index) -> !fir.boxchar<1>
520+
omp.yield(%2 : !fir.boxchar<1>)
521+
} copy {
522+
^bb0(%arg0: !fir.boxchar<1>, %arg1: !fir.boxchar<1>):
523+
hlfir.assign %arg0 to %arg1 : !fir.boxchar<1>, !fir.boxchar<1>
524+
omp.yield(%arg1 : !fir.boxchar<1>)
525+
} dealloc {
526+
^bb0(%arg0: !fir.boxchar<1>):
527+
%0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
528+
%1 = fir.convert %0#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.heap<!fir.char<1,?>>
529+
fir.freemem %1 : !fir.heap<!fir.char<1,?>>
530+
omp.yield
531+
}
498532
}

0 commit comments

Comments
 (0)