| Issue |
208318
|
| Summary |
`IMAGE_INDEX` lowered argument type mismatch leads to erroneous runtime results (especially for corank > 1)
|
| Labels |
flang:ir
|
| Assignees |
JDPailleux
|
| Reporter |
bonachea
|
The recent merge of #192944 included a defect in the `IMAGE_INDEX` intrinsic, believed to affect all coarray arguments but especially those with corank > 1.
MRE:
```fortran
program coarray_image_index
integer :: coarray1[10:*]
integer :: coarray2[10:20, 30:*]
integer :: coarray3[10:20, 30:40, 50:*]
write(*,'(A,I4)') "IMAGE_INDEX(coarray1)= ", IMAGE_INDEX(coarray1,[10])
write(*,'(A,I4)') "IMAGE_INDEX(coarray2)= ", IMAGE_INDEX(coarray2,[10,30])
write(*,'(A,I4)') "IMAGE_INDEX(coarray3)= ", IMAGE_INDEX(coarray3,[10,30,50])
end program
```
Expected correct output (verified from a single-image run of NAG 7.2):
```
IMAGE_INDEX(coarray1)= 1
IMAGE_INDEX(coarray2)= 1
IMAGE_INDEX(coarray3)= 1
```
Flang's incorrect output: (from `main` @ e2d6498e3623)
```
pm$ flang --version
flang version 23.0.0git ([email protected]:llvm/llvm-project.git e2d6498e36235ecd9955d8d375a0c1a253c2e11a)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: <redacted>/llvm/inst/bin
Build config: +assertions
pm$ flang -fcoarray -O0 -g image-index-bug.F90 -L../caffeine/inst-llvm23dev-debug/lib/ -lcaffeine-smp-seq -lgasnet-smp-seq -L/opt/cray/pe/pmi/default/lib -lpmi && env GASNET_PSHM_NODES=1 a.out
warning: Support for multi image Fortran features is still experimental and in development.
IMAGE_INDEX(coarray1)= 1
IMAGE_INDEX(coarray2)= 0
IMAGE_INDEX(coarray3)= 0
```
Using a debugger I've observed what appears to be incorrect values passed in the `sub` argument to `prif::prif_image_index` for corank > 1, here is the corank==3 call:
```
Breakpoint 4, prif::prif_image_index (coarray_handle=..., sub=..., image_index=21845)
at <redacted>/caffeine/src/caffeine/coarray_queries_s.F90:136
136 call image_index_helper(coarray_handle, sub, current_team, image_index)
(gdb) where
#0 prif::prif_image_index (coarray_handle=..., sub=..., image_index=21845)
at <redacted>/caffeine/src/caffeine/coarray_queries_s.F90:136
#1 0x00005555555606c9 in COARRAY_IMAGE_INDEX () at image-index-bug.F90:7
(gdb) print sub(1)
$1 = 128849018890
(gdb) print sub(2)
$2 = 214748364830
(gdb) print sub(3)
$3 = 50
(gdb) print/x sub(1)
$4 = 0x1e0000000a
(gdb) print/x sub(2)
$5 = 0x320000001e
(gdb) print/x sub(3)
$6 = 0x32
```
Note that the high words of `sub(1)` and `sub(2)` appear to have been corrupted, and the garbage is exactly the low word of the next higher array element. This is consistent with a defect where array values are incorrectly passed as 32-bit integers when a 64-bit integer array is expected by the `sub` argument to `prif::prif_image_index`. The semantics of `prif::prif_image_index` is such that passing garbage values in `sub()` (outside the cobounds of the coarray dummy argument) produce a resulting `image_index` of 0, and that's exactly the code path the debugger observes for the corank 2 and 3 calls above.
Dumping relevant MLIR:
```
pm$ flang -fcoarray -O0 -g image-index-bug.F90 -c -mmlir --mlir-print-ir-after=mif-convert 2>&1 | grep -B8 'fir.call @_QMprifPprif_image_index'
%86 = fir.address_of(@_QQro.1xi4.0) : !fir.ref<!fir.array<1xi32>>
%87 = fir.shape %c1 : (index) -> !fir.shape<1>
%88 = fir.declare %86(%87) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1xi4.0"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<1xi32>>
%89 = fir.embox %34 : (!fir.ref<i32>) -> !fir.box<i32, corank:1>
%90 = fir.embox %88(%87) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
%91 = fir.address_of(@_QFEcoarray1_coarray_handle) : !fir.ref<!fir.box<none>>
%92 = fir.load %91 : !fir.ref<!fir.box<none>>
%93 = fir.convert %90 : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi64>>
fir.call @_QMprifPprif_image_index(%92, %93, %2) : (!fir.box<none>, !fir.box<!fir.array<?xi64>>, !fir.ref<i32>) -> ()
--
%104 = fir.address_of(@_QQro.2xi4.1) : !fir.ref<!fir.array<2xi32>>
%105 = fir.shape %c2 : (index) -> !fir.shape<1>
%106 = fir.declare %104(%105) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2xi4.1"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<2xi32>>
%107 = fir.embox %52 : (!fir.ref<i32>) -> !fir.box<i32, corank:2>
%108 = fir.embox %106(%105) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
%109 = fir.address_of(@_QFEcoarray2_coarray_handle) : !fir.ref<!fir.box<none>>
%110 = fir.load %109 : !fir.ref<!fir.box<none>>
%111 = fir.convert %108 : (!fir.box<!fir.array<2xi32>>) -> !fir.box<!fir.array<?xi64>>
fir.call @_QMprifPprif_image_index(%110, %111, %1) : (!fir.box<none>, !fir.box<!fir.array<?xi64>>, !fir.ref<i32>) -> ()
--
%122 = fir.address_of(@_QQro.3xi4.2) : !fir.ref<!fir.array<3xi32>>
%123 = fir.shape %c3 : (index) -> !fir.shape<1>
%124 = fir.declare %122(%123) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3xi4.2"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<3xi32>>
%125 = fir.embox %72 : (!fir.ref<i32>) -> !fir.box<i32, corank:3>
%126 = fir.embox %124(%123) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
%127 = fir.address_of(@_QFEcoarray3_coarray_handle) : !fir.ref<!fir.box<none>>
%128 = fir.load %127 : !fir.ref<!fir.box<none>>
%129 = fir.convert %126 : (!fir.box<!fir.array<3xi32>>) -> !fir.box<!fir.array<?xi64>>
fir.call @_QMprifPprif_image_index(%128, %129, %0) : (!fir.box<none>, !fir.box<!fir.array<?xi64>>, !fir.ref<i32>) -> ()
```
Note the `sub` argument is produced by `fir.convert : (!fir.box<!fir.array<3xi32>>) -> !fir.box<!fir.array<?xi64>>`, but there doesn't appear to be allocation of a temporary 64-bit integer array as I'd expect.
This problem only _seems_ to affect coarrays with corank > 1, but I suspect that's just because corank==1 is reading a high word from out-of-bounds memory that happens to be zero.
CC: @ktras @rouson
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs