Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28335 Discussions

Optimization causes structure fields to be assigned incorrectly


We are in the process of upgrading several hydrodynamics libraries from Intel® Parallel Studio XE 2015 with Visual Studio 2010 to the Intel Fortran Compiler that is part of the oneAPI with Visual Studio 2019.

We uncovered some weird behavior when compiling with /O2 optimizations. When copying data into a structure field, the result is mis-aligned and ends up in the wrong fields. 

Here are the structures in question:

	structure /coord_2d/
	  real north
	  real east
	end structure	       

        structure /other_ships_structure/

         character*120       object_id
	   record /coord_2d/   position	             ! east, north position
	   real                heading	             ! degrees
	   real                length	                 ! feet
	   real                beam	                 ! feet
         real                draft                   ! feet
         real                displacement            ! L.T.
         real                forward_velocity        ! ft/sec
         real                transverse_velocity     ! ft/sec
         real                yaw_velocity            ! deg/sec
         record /fender_input_structure / fender

       end structure

 There is code that copies the data from one instance of this structure (ios -> data passed in from a C++ application that gathers the data) to another instance (ext -> internal data use in processing). Both ext.fndr.tships and ios.tships use the same structure.

	ext.fndr.num_other_ships = ios.num_other_ships

      do i = 1, ext.fndr.num_other_ships
        ext.fndr.tships(i).object_id      = ios.tships(i).object_id
	  ext.fndr.tships(i).position.east  = ios.tships(i).position.east
	  ext.fndr.tships(i).position.north = ios.tships(i).position.north
       write(*,*) ext.fndr.tships(i).position.north, ext.fndr.tships(i).position.east, ext.fndr.tships(i).heading
	  ext.fndr.tships(i).heading        = ios.tships(i).heading
	  ext.fndr.tships(i).length         = ios.tships(i).length
	  ext.fndr.tships(i).beam           = ios.tships(i).beam

The write() command prints out the variables after position.east and position.north have been assigned. When compiled with /O2, the particular test has the following input:

ios.tships(i).position.east -> 94

ios.tships(i).position.north -> 1183

ext.fndr.tships(i).position.east -> 1183

ext.fndr.tships(i).position.north -> 0

ext.fndr.tships(i).heading -> 94

As you can see, the values get assigned essentially 4 bytes over, and end up in position.east and heading rather than in position.east and position.north.

If I compile this library optimizations disabled or with /O1, the assignment works correctly and the right values are in the fields.

Additionally, if I switch the call order (copy position.north first, and then position.east), it works correctly.

As you can imagine, this is a little unsettling and potentially indicative of other, currently hidden, assignment errors throughout our Fortran code base. Hopefully someone has an explanation that will allow us to fix this issue.

0 Kudos
0 Replies