Skip to content

Commit e6618aa

Browse files
authored
[flang] fix ignore_tkr(tk) with character dummy (#108168)
The test code with ignore_tkr(tk) on character dummy passed by fir.boxchar<> was crashing the compiler in [an assert](https://github.com/llvm/llvm-project/blob/2afe678f0a246387977a8ca694d4489e2c868991/flang/lib/Optimizer/Dialect/FIRType.cpp#L632) in `changeElementType`. It makes little sense to call changeElementType on a fir.boxchar since this type is lossy (the shape is not part of it). Just skip it in the code dealing with ignore(tk) when hitting this case
1 parent 165f0e8 commit e6618aa

File tree

5 files changed

+62
-17
lines changed

5 files changed

+62
-17
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,10 +1193,26 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
11931193
// is set (descriptors must be created with the actual type in this case, and
11941194
// copy-in/copy-out should be driven by the contiguity with regard to the
11951195
// actual type).
1196-
if (ignoreTKRtype)
1197-
dummyTypeWithActualRank = fir::changeElementType(
1198-
dummyTypeWithActualRank, actual.getFortranElementType(),
1199-
actual.isPolymorphic());
1196+
if (ignoreTKRtype) {
1197+
if (auto boxCharType =
1198+
mlir::dyn_cast<fir::BoxCharType>(dummyTypeWithActualRank)) {
1199+
auto maybeActualCharType =
1200+
mlir::dyn_cast<fir::CharacterType>(actual.getFortranElementType());
1201+
if (!maybeActualCharType ||
1202+
maybeActualCharType.getFKind() != boxCharType.getKind()) {
1203+
// When passing to a fir.boxchar with ignore(tk), prepare the argument
1204+
// as if only the raw address must be passed.
1205+
dummyTypeWithActualRank =
1206+
fir::ReferenceType::get(actual.getElementOrSequenceType());
1207+
}
1208+
// Otherwise, the actual is already a character with the same kind as the
1209+
// dummy and can be passed normally.
1210+
} else {
1211+
dummyTypeWithActualRank = fir::changeElementType(
1212+
dummyTypeWithActualRank, actual.getFortranElementType(),
1213+
actual.isPolymorphic());
1214+
}
1215+
}
12001216

12011217
PreparedDummyArgument preparedDummy;
12021218

flang/lib/Optimizer/Builder/FIRBuilder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,9 @@ mlir::Value fir::FirOpBuilder::convertWithSemantics(
444444
// argument in characters and use it as the length of the string
445445
auto refType = getRefType(boxType.getEleTy());
446446
mlir::Value charBase = createConvert(loc, refType, val);
447-
mlir::Value unknownLen = create<fir::UndefOp>(loc, getIndexType());
447+
// Do not use fir.undef since llvm optimizer is too harsh when it
448+
// sees such values (may just delete code).
449+
mlir::Value unknownLen = createIntegerConstant(loc, getIndexType(), 0);
448450
fir::factory::CharacterExprHelper charHelper{*this, loc};
449451
return charHelper.createEmboxChar(charBase, unknownLen);
450452
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
! Test ignore_tkr(tk) with character dummies
2+
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
3+
4+
module test_char_tk
5+
interface
6+
subroutine foo(c)
7+
character(1)::c(*)
8+
!dir$ ignore_tkr(tkrdm) c
9+
end subroutine
10+
end interface
11+
contains
12+
subroutine test_normal()
13+
character(1) :: c(10)
14+
call foo(c)
15+
end subroutine
16+
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_normal(
17+
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %{{.*}}, %c1{{.*}}: (!fir.ref<!fir.char<1>>, index) -> !fir.boxchar<1>
18+
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
19+
subroutine test_normal2()
20+
character(10) :: c(10)
21+
call foo(c)
22+
end subroutine
23+
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_normal2(
24+
!CHECK: %[[VAL_4:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10x!fir.char<1,10>>>) -> !fir.ref<!fir.char<1,10>>
25+
!CHECK: %[[VAL_5:.*]] = fir.emboxchar %[[VAL_4]], %c10{{.*}}: (!fir.ref<!fir.char<1,10>>, index) -> !fir.boxchar<1>
26+
!CHECK: fir.call @_QPfoo(%[[VAL_5]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
27+
subroutine test_weird()
28+
real :: c(10)
29+
call foo(c)
30+
end subroutine
31+
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_weird(
32+
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
33+
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
34+
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
35+
end module

flang/test/Lower/call-suspect.f90

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,18 @@
22
! are accepted regardless to maintain backwards compatibility with
33
! other Fortran implementations.
44

5-
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
5+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
66

77
! CHECK-LABEL: func @_QPs1() {
8-
! CHECK: %[[cast:.*]] = fir.convert %{{.*}} : (!fir.ref<f32>) -> !fir.ref<!fir.char<1,?>>
9-
! CHECK: %[[undef:.*]] = fir.undefined index
10-
! CHECK: %[[box:.*]] = fir.emboxchar %[[cast]], %[[undef]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
11-
! CHECK: fir.call @_QPs3(%[[box]]) {{.*}}: (!fir.boxchar<1>) -> ()
8+
! CHECK: fir.convert %{{.*}} : ((!fir.boxchar<1>) -> ()) -> ((!fir.ref<f32>) -> ())
129

1310
! Pass a REAL by reference to a subroutine expecting a CHARACTER
1411
subroutine s1
1512
call s3(r)
1613
end subroutine s1
1714

1815
! CHECK-LABEL: func @_QPs2(
19-
! CHECK: %[[ptr:.*]] = fir.box_addr %{{.*}} : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
20-
! CHECK: %[[cast:.*]] = fir.convert %[[ptr]] : (!fir.ptr<f32>) -> !fir.ref<!fir.char<1,?>>
21-
! CHECK: %[[undef:.*]] = fir.undefined index
22-
! CHECK: %[[box:.*]] = fir.emboxchar %[[cast]], %[[undef]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
23-
! CHECK: fir.call @_QPs3(%[[box]]) {{.*}}: (!fir.boxchar<1>) -> ()
16+
! CHECK: fir.convert %{{.*}} : ((!fir.boxchar<1>) -> ()) -> ((!fir.ref<f32>) -> ())
2417

2518
! Pass a REAL, POINTER data reference to a subroutine expecting a CHARACTER
2619
subroutine s2(p)

flang/test/Lower/implicit-call-mismatch.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ subroutine test_conversion_from_proc
135135

136136
! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
137137
! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<!fir.char<1,?>>
138-
! CHECK: %[[len:.*]] = fir.undefined index
139-
! CHECK: %[[box:.*]] = fir.emboxchar %[[convert]], %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
138+
! CHECK: %[[box:.*]] = fir.emboxchar %[[convert]], %c0{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
140139
! CHECK: fir.call @_QPpass_char_to_proc(%[[box]])
141140
call pass_char_to_proc(proc)
142141

0 commit comments

Comments
 (0)