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

Intrinsic `transfer` with a provided size: (un)expected behavior?

Jeremie_V_
Beginner
992 Views

Dear,

 

Here is a small Fortran program to reproduce the reason of my question:

```fortran

program test
use iso_fortran_env, only: int32, int16
implicit none
integer(int32), parameter :: m1 = int(z'776BF593', int32)
integer(int16), parameter :: m116(2) = transfer( m1, 0_int16, 2 )


print*, 'Should ', transfer(m116, 0_int32), ' be equal to ', m1, '?'

write(*,'(b32.32)')     m1
write(*,'(2(b16.16))') m116

end program

```

Based on the Intel documentation of the intrinsic `transfer` that mentions "...Otherwise, the result contains the bit pattern contained in source", I was expecting that the `m116` defined as `m116(2) = transfer(m1, 0_int16, 2)` would have the same bit pattern as `m1`. However, this is not the case for the last bit (sign bit?).

Is the application of `transfer` on this last bit processor-dependent, as `m1` and `m116` are `integer`? 

 

In advance thank you.

 

* OS: Fedora 34

* Compiler: ifort (IFORT) 2021.4.0 20210910

 

Labels (2)
0 Kudos
1 Solution
Devorah_H_Intel
Moderator
910 Views

Thank you for your report. This issue has been escalated to compiler engineering. 

View solution in original post

0 Kudos
5 Replies
wclodius
Beginner
982 Views

FWIW on my machine M116 differs from m1 in more than the first bit. The two elements of m116 have the same value [-2669,-2669] while gfortran gives [-2669,  30571]. It appears that m116(2) = transfer( m1, 0_int16, 2 ), instead of transferring all 32 bits to m116, is just replicating the first 16 bits twice. For transfer, I would expect something similar to a C type cast of a 32 bit integer to a pair of overlaid 16 bit integers, which is what I get from gfortran.

 

0 Kudos
Jeremie_V_
Beginner
972 Views

Following the meassage of @wclodius , I had a closer look, and indeed, more than 1 bit changed.

Here are the result for ifort 2021.4.0:

```

m116 -2669 -2669
-174852717 should be equal to 2003563923 ?
01110111011010111111010110010011
11110101100100111111010110010011

```

 

I can reproduce this behaviour with `ifx 2021.4.0` and `ifort 17.0.0`

0 Kudos
Jeremie_V_
Beginner
961 Views

This seems to be a bug when `transfer` is used with `parameter`, because when used without `parameter`, the back-transfer returns the original result.

```

program test
use iso_fortran_env, only: int32, int16
implicit none
integer(int32), parameter :: m1 = int(z'776BF593', int32)
integer(int16), parameter :: m116(2) = transfer( m1, 0_int16, 2 )
integer(int16) :: m216(2)

print*,'m116 ',m116

m216 = transfer( m1, 0_int16, 2 )
print*,'m216 ',m216

print*,transfer(m116, 0_int32), ' should be equal to ', m1,'?'
print*,transfer(m216, 0_int32), ' should be equal to ', m1,'?'

write(*,'(b32.32)')m1
write(*,'(2(b16.16))')m116
write(*,'(2(b16.16))')m216
end program

```

output:

```

m116 -2669 -2669
m216 -2669 30571
-174852717 should be equal to 2003563923 ?
2003563923 should be equal to 2003563923 ?
01110111011010111111010110010011
11110101100100111111010110010011
11110101100100110111011101101011

```

0 Kudos
Devorah_H_Intel
Moderator
911 Views

Thank you for your report. This issue has been escalated to compiler engineering. 

0 Kudos
Jeremie_V_
Beginner
896 Views

Thank you.

0 Kudos
Reply