Skip to content

[AArch64] Incorrect load after #142941 #150004

@kawashima-fj

Description

@kawashima-fj

After the merge of #142941 (e8a891b), the following Fortran program prints incorrect result on -O2 or higher.

program main
   integer :: i, k
   k = 0

   write(10, *) 0
   write(10, *) 1
   write(10, *) 2
   write(10, *) 3
   write(10, *) 4
   write(10, *) 5
   write(10, *) 6
   write(10, *) 7
   write(10, *) 8
   write(10, *) 9

   rewind 10

   read(10, *) i; if (i /= 0) k = k + 1
   read(10, *) i; if (i /= 1) k = k + 1
   read(10, *) i; if (i /= 2) k = k + 1
   read(10, *) i; if (i /= 3) k = k + 1
   read(10, *) i; if (i /= 4) k = k + 1
   read(10, *) i; if (i /= 5) k = k + 1
   read(10, *) i; if (i /= 6) k = k + 1
   read(10, *) i; if (i /= 7) k = k + 1
   read(10, *) i; if (i /= 8) k = k + 1
   read(10, *) i; if (i /= 9) k = k + 1

   print *, k

end program main
$ flang -O0 test2.f90 && ./a.out
 0
$ flang -O1 test2.f90 && ./a.out
 0
$ flang -O2 test2.f90 && ./a.out
 4
$ flang -O3 test2.f90 && ./a.out
 4

This program writes ten values to a file and read the written values. If a read value is not the expected one, it increments k.

Before e8a891b, it prints 0 for all optimization levels. It's the expected behavior.

Comparing assembly before and after the commit shows that there are differences in how i values are loaded after read.

@@ -188,12 +188,9 @@
        bl      _FortranAioInputInteger
        mov     x0, x20
        bl      _FortranAioEndIoStatement
-       ldr     q0, [sp, #16]
        mov     w0, #10
        mov     x1, x19
        mov     w2, #22
-       ld1     { v0.s }[1], [x21]
-       str     q0, [sp, #16]
        bl      _FortranAioBeginExternalListInput
        add     x1, x29, #28
        mov     w2, #4
@@ -201,12 +198,9 @@
        bl      _FortranAioInputInteger
        mov     x0, x20
        bl      _FortranAioEndIoStatement
-       ldr     q0, [sp, #16]
        mov     w0, #10
        mov     x1, x19
        mov     w2, #23
-       ld1     { v0.s }[2], [x21]
-       str     q0, [sp, #16]
        bl      _FortranAioBeginExternalListInput
        add     x1, x29, #28
        mov     w2, #4
@@ -214,11 +208,14 @@
        bl      _FortranAioInputInteger
        mov     x0, x20
        bl      _FortranAioEndIoStatement
-       ldr     q0, [sp, #16]
+       ldr     q1, [sp, #16]
        mov     w0, #10
        mov     x1, x19
        mov     w2, #24
-       ld1     { v0.s }[3], [x21]
+       ld1     { v1.s }[1], [x22]
+       ldr     s0, [x22]
+       ld1     { v0.s }[1], [x22]
+       zip1    v0.2d, v1.2d, v0.2d
        str     q0, [sp, #16]
        bl      _FortranAioBeginExternalListInput
        add     x1, x29, #28

#149703 does not fix this problem.

@jcohen-apple Could you take a look?

The LLVM IR by flang -O2 -S -emit-llvm test.f90, assembly before e8a891b, assembly after e8a891b are attached.

I ported this program to C using fprintf/fscanf but I could not reproduce the problem.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions