# An interesting difference between compilers

**URL:** https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131
**Category:** Help
**Created:** [January 7, 2024, 11:12pm UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131 "2024-01-07T23:12:10Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Andrii](https://avatars.discourse-cdn.com/v4/letter/a/77aa72/32.png) [@Andrii](https://fortran-lang.discourse.group/u/Andrii)
#### Post date: [January 7, 2024, 11:12pm UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/1 "2024-01-07T23:12:10Z")

</div>

Hi all,

recently I’ve submitted some simple fixes to one Fortran project and noticed a difference in results if the project compiled with different compilers.  
After some more checks it became clear that there are two group of compilers with different behaviour.  
“A” GNU,Intel/InteLLVM,lfortran,NAG,IBM. (expected results)  
“B” AOCC, NVidia, ARM. (problematic results)

In the end the main author of the code has created a reproducer of the problem and I’ve stripped it to the following code.

```auto
program aocc_run_test
  implicit none
  real :: arr_in1(0:10, 2:5), arr1(0:10,2:5)
  real :: arr_in2(0:10, 2:5), arr2(0:10,2:5)
  real :: arr_in3(0:10, 2:5), arr3(0:10,2:5)
  integer i, j
  do i=0,10 
  do j=2,5
    arr_in1(i,j) = 1000*i+j
    arr_in2(i,j) = 1000*i+j
    arr_in3(i,j) = 1000*i+j
  end do
  end do

  call evaluate(arr_in1,arr_in2,arr_in3,arr1,arr2,arr3)
contains

  function justcopy(arr_in) 
   real, intent(in) :: arr_in(0:,:)
   real :: justcopy(0:ubound(arr_in,dim=1), 2:5) !This works for "A" GNU,Intel/InteLLVM,lfortran,NAG,IBM. Does not work for "B" AOCC, NVidia, ARM.
! real :: justcopy(0:size(arr_in,dim=1)-1, 2:5) !This works for all compilers
   write(*,*)lbound(arr_in,dim=1),ubound(arr_in,dim=1),size(arr_in,1)
   write(*,*)lbound(arr_in,dim=2),ubound(arr_in,dim=2),size(arr_in,2)
   write(*,*)lbound(justcopy,dim=1),ubound(justcopy,dim=1),size(justcopy,1)
   justcopy=arr_in
   write(*,*)lbound(justcopy,dim=1),ubound(justcopy,dim=1),size(justcopy,1)
  end function justcopy
  
  subroutine evaluate(arr_in1,arr_in2,arr_in3,arr_out1,arr_out2,arr_out3)
    real, intent(in) :: arr_in1(:,:)
    real, intent(in) :: arr_in2(:,:)
    real, intent(in) :: arr_in3(:,:)
    real, intent(out) :: arr_out1(:,:)
    real, intent(out) :: arr_out2(:,:)
    real, intent(out) :: arr_out3(:,:)
    real, allocatable :: X(:,:)

    arr_out1 = justcopy(arr_in1)
    X = justcopy(arr_in2)       
    arr_out2 = X
    arr_out3 = 1.0*justcopy(arr_in3)

    write(*,*)"X-- ", lbound(X), ubound(X),size(X,1) !This line is different for "A" and "B" compilers with "ubound"
    write(*,*)X
    write(*,*)"arr_out1--", lbound(arr_out1), ubound(arr_out1),size(arr_out1,1)
    write(*,*)arr_out1
    write(*,*)"arr_out2--", lbound(arr_out2), ubound(arr_out2),size(arr_out2,1)
    write(*,*)arr_out2
    write(*,*)"arr_out3--", lbound(arr_out3), ubound(arr_out3),size(arr_out3,1)
    write(*,*)arr_out3
    !With ubound arr_out3=arr_out2 != arr_out1 != X
  end subroutine evaluate  
end program aocc_run_test

```

It seems the main difference is the way the specification part of the code work. I have looked into the 7.1.11 of [https://j3-fortran.org/doc/year/10/10-007r1.pdf](https://j3-fortran.org/doc/year/10/10-007r1.pdf) and my reading is that the code with `ubound` should work, as `ubound` is allowed in the specification. But I’m not sure and would appreciate hearing your opinion on this.

Best regards,

Andrii

---

<div class="post-metadata">

### Author: ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)
#### Post date: [January 8, 2024, 12:10am UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/2 "2024-01-08T00:10:57Z")

</div>

It might help us if you’ll say what the expected and unexpected results are. I don’t have access to any of the group B compilers.

---

<div class="post-metadata">

### Author: ![Andrii](https://avatars.discourse-cdn.com/v4/letter/a/77aa72/32.png) [@Andrii](https://fortran-lang.discourse.group/u/Andrii)
#### Post date: [January 8, 2024, 9:14am UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/3 "2024-01-08T09:14:35Z")

</div>

Dear @sblionel,

please see the results attached.

The bad case works as if the `ubound(arr_in)`is evaluated first and only then the lower boundary of `arr_in` is set to 0.

Best regards,

Andrii

good

```auto
           0 10 11
           1 4 4
           0 10 11
           0 10 11
           0 10 11
           1 4 4
           0 10 11
           0 10 11
           0 10 11
           1 4 4
           0 10 11
           0 10 11
 X-- 1 1 11 4 11
   2.00000000 1002.00000 2002.00000 3002.00000 4002.00000 5002.00000 6002.00000 7002.00000 8002.00000 9002.00000 10002.0000 3.00000000 1003.00000 2003.00000 3003.00000 4003.00000 5003.00000 6003.00000 7003.00000 8003.00000 9003.00000 10003.0000 4.00000000 1004.00000 2004.00000 3004.00000 4004.00000 5004.00000 6004.00000 7004.00000 8004.00000 9004.00000 10004.0000 5.00000000 1005.00000 2005.00000 3005.00000 4005.00000 5005.00000 6005.00000 7005.00000 8005.00000 9005.00000 10005.0000    
 arr_out1-- 1 1 11 4 11
   2.00000000 1002.00000 2002.00000 3002.00000 4002.00000 5002.00000 6002.00000 7002.00000 8002.00000 9002.00000 10002.0000 3.00000000 1003.00000 2003.00000 3003.00000 4003.00000 5003.00000 6003.00000 7003.00000 8003.00000 9003.00000 10003.0000 4.00000000 1004.00000 2004.00000 3004.00000 4004.00000 5004.00000 6004.00000 7004.00000 8004.00000 9004.00000 10004.0000 5.00000000 1005.00000 2005.00000 3005.00000 4005.00000 5005.00000 6005.00000 7005.00000 8005.00000 9005.00000 10005.0000    
 arr_out2-- 1 1 11 4 11
   2.00000000 1002.00000 2002.00000 3002.00000 4002.00000 5002.00000 6002.00000 7002.00000 8002.00000 9002.00000 10002.0000 3.00000000 1003.00000 2003.00000 3003.00000 4003.00000 5003.00000 6003.00000 7003.00000 8003.00000 9003.00000 10003.0000 4.00000000 1004.00000 2004.00000 3004.00000 4004.00000 5004.00000 6004.00000 7004.00000 8004.00000 9004.00000 10004.0000 5.00000000 1005.00000 2005.00000 3005.00000 4005.00000 5005.00000 6005.00000 7005.00000 8005.00000 9005.00000 10005.0000    
 arr_out3-- 1 1 11 4 11
   2.00000000 1002.00000 2002.00000 3002.00000 4002.00000 5002.00000 6002.00000 7002.00000 8002.00000 9002.00000 10002.0000 3.00000000 1003.00000 2003.00000 3003.00000 4003.00000 5003.00000 6003.00000 7003.00000 8003.00000 9003.00000 10003.0000 4.00000000 1004.00000 2004.00000 3004.00000 4004.00000 5004.00000 6004.00000 7004.00000 8004.00000 9004.00000 10004.0000 5.00000000 1005.00000 2005.00000 3005.00000 4005.00000 5005.00000 6005.00000 7005.00000 8005.00000 9005.00000 10005.0000    

```

bad

```auto
            0 10 11
            1 4 4
            0 10 11
            0 10 11
            0 10 11
            1 4 4
            0 10 11
            0 10 11
            0 10 11
            1 4 4
            0 10 11
            0 10 11
 X-- 0 2 11 5 12
    2.000000 1002.000 2002.000 3002.000     
    4002.000 5002.000 6002.000 7002.000     
    8002.000 9002.000 10002.00 3.000000     
    1003.000 2003.000 3003.000 4003.000     
    5003.000 6003.000 7003.000 8003.000     
    9003.000 10003.00 4.000000 1004.000     
    2004.000 3004.000 4004.000 5004.000     
    6004.000 7004.000 8004.000 9004.000     
    10004.00 5.000000 1005.000 2005.000     
    3005.000 4005.000 5005.000 6005.000     
    7005.000 8005.000 9005.000 10005.00     
    0.000000 0.000000 0.000000 0.000000    
 arr_out1-- 1 1 11 4 11
    2.000000 1002.000 2002.000 3002.000     
    4002.000 5002.000 6002.000 7002.000     
    8002.000 9002.000 10002.00 3.000000     
    1003.000 2003.000 3003.000 4003.000     
    5003.000 6003.000 7003.000 8003.000     
    9003.000 10003.00 4.000000 1004.000     
    2004.000 3004.000 4004.000 5004.000     
    6004.000 7004.000 8004.000 9004.000     
    10004.00 5.000000 1005.000 2005.000     
    3005.000 4005.000 5005.000 6005.000     
    7005.000 8005.000 9005.000 10005.00    
 arr_out2-- 1 1 11 4 11
    2.000000 1002.000 2002.000 3002.000     
    4002.000 5002.000 6002.000 7002.000     
    8002.000 9002.000 10002.00 1003.000     
    2003.000 3003.000 4003.000 5003.000     
    6003.000 7003.000 8003.000 9003.000     
    10003.00 4.000000 2004.000 3004.000     
    4004.000 5004.000 6004.000 7004.000     
    8004.000 9004.000 10004.00 5.000000     
    1005.000 3005.000 4005.000 5005.000     
    6005.000 7005.000 8005.000 9005.000     
    10005.00 0.000000 0.000000 0.000000    
 arr_out3-- 1 1 11 4 11
    2.000000 1002.000 2002.000 3002.000     
    4002.000 5002.000 6002.000 7002.000     
    8002.000 9002.000 10002.00 1003.000     
    2003.000 3003.000 4003.000 5003.000     
    6003.000 7003.000 8003.000 9003.000     
    10003.00 4.000000 2004.000 3004.000     
    4004.000 5004.000 6004.000 7004.000     
    8004.000 9004.000 10004.00 5.000000     
    1005.000 3005.000 4005.000 5005.000     
    6005.000 7005.000 8005.000 9005.000     
    10005.00 0.000000 0.000000 0.000000    

```

---

<div class="post-metadata">

### Author: ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)
#### Post date: [January 8, 2024, 7:03pm UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/4 "2024-01-08T19:03:53Z")

</div>

Thanks for that. Group B compilers are wrong here, probably misunderstanding the rules for `lbound` and `ubound` for non-pointer dummy arguments.

---

<div class="post-metadata">

### Author: ![Andrii](https://avatars.discourse-cdn.com/v4/letter/a/77aa72/32.png) [@Andrii](https://fortran-lang.discourse.group/u/Andrii)
#### Post date: [January 9, 2024, 10:19am UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/5 "2024-01-09T10:19:56Z")

</div>

Dear @sblionel,

thank you very much for the input. I will also try to fill some bugreports and if there will be feedback, I will post it here.

Best regards,

Andrii

---

<div class="post-metadata">

### Author: ![gak](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gak/32/146_2.png) [@gak](https://fortran-lang.discourse.group/u/gak)
#### Post date: [January 11, 2024, 7:13am UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/6 "2024-01-11T07:13:34Z")

</div>

I’ve been removed from this for a while, but I think AOCC and Arm are based on Classic Flang, which was derived from the NVIDIA compiler. That could explain all the Group B behavior.

---

<div class="post-metadata">

### Author: ![Andrii](https://avatars.discourse-cdn.com/v4/letter/a/77aa72/32.png) [@Andrii](https://fortran-lang.discourse.group/u/Andrii)
#### Post date: [January 11, 2024, 8:14am UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/7 "2024-01-11T08:14:23Z")

</div>

Yes, we have noted that the common property of the compilers in B group is LLVM backend (it seems the IBM v17 compiler belongs to the group B). But I’m still not sure, as IntelLLVM has the same backend and the genealogy of the compilers is not very clear for me – the name “flang” is used too often.

---

<div class="post-metadata">

### Author: ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)
#### Post date: [January 11, 2024, 4:49pm UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/8 "2024-01-11T16:49:56Z")

</div>

@Andrii thanks for trying all compilers, and I am happy that LFortran worked for this, we are still in alpha, so it’s always a pleasant surprise for me when it actually works.

This bug is not due to using LLVM (LFortran also uses LLVM), but due to the front end and middle end of the compiler, which determines how these intrinsic functions `l/ubound` should behave and how they should be lowered to LLVM.

---

<div class="post-metadata">

### Author: ![bcornille](https://avatars.discourse-cdn.com/v4/letter/b/6f9a4e/32.png) [@bcornille](https://fortran-lang.discourse.group/u/bcornille)
#### Post date: [January 12, 2024, 12:31pm UTC](https://fortran-lang.discourse.group/t/an-interesting-difference-between-compilers/7131/9 "2024-01-12T12:31:24Z")

</div>

flang-new/llvm-flang also produces the “good” result.
