<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/106682>106682</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Flang] TSVC: not vectorized because loops are not recognized as reduction loops
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            flang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          s-watanabe314
      </td>
    </tr>
</table>

<pre>
    Flang can't vectorize the loops in s314, s316, s3111 and s3113 of TSVC while Clang can vectorize the loops written in C.
```Fortran
! Fortran version s314
      do 1 nl = 1,ntimes
      x = a(1)
      do 10 i = 2,n
 if(a(i) .gt. x) x = a(i)
   10 continue
      call dummy(ld,n,a,b,c,d,e,aa,bb,cc,x)
   1  continue
```
```C
// C version s314
for (int nl = 0; nl < ntimes; nl++) {
  x = a[0];
  for (int i = 1; i < n; i++) {
    if (a[i] > x) {
      x = a[i];
 }
  }
  dummy(a, b, c, d, e, aa, bb, cc, x);
}
```
```
$ flang-new -v -Ofast s314.f -S -emit-llvm -Rpass=vector
flang-new version 20.0.0git (https://github.com/llvm/llvm-project.git 2a50dac9fb034a39ace861f7feb60c43ba23e53c)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /path/to/install/bin
Build config: +unoptimized, +assertions
Found candidate GCC installation: /path/to/lib/gcc/aarch64-redhat-linux/11
Selected GCC installation: /path/to/lib/gcc/aarch64-redhat-linux/11
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/path/to/install/bin/flang-new" -fc1 -triple aarch64-unknown-linux-gnu -emit-llvm -fcolor-diagnostics -mrelocation-model pic -pic-level 2 -pic-is-pie -ffast-math -target-cpu generic -target-feature +outline-atomics -target-feature +v8a -target-feature +fp-armv8 -target-feature +neon -fstack-arrays -fversion-loops-for-stride -Rpass=vector -resource-dir /path/to/lib/clang/20 -mframe-pointer=non-leaf -O3 -o s314.ll -x f95-cpp-input s314.f
$ clang -Ofast s314.c -S -emit-llvm -Rpass=vector
clang: warning: argument '-Ofast' is deprecated; use '-O3 -ffast-math' for the same behavior, or '-O3' to enable only conforming optimizations [-Wdeprecated-ofast]
s314.c:17:3: remark: vectorized loop (vectorization width: 4, interleaved count: 2) [-Rpass=loop-vectorize]
 17 |                 for (int i = 1; i < LEN; i++) {
      | 
```
There seems to be a redundant store in the IR from Flang and that prevents from the pattern match.  
This might be caused by the LICM pass failing to move store instructions within the inner loop outside the loop when dealing with nested loops.
- IR from Flang
```
24: ; preds = %.lr.ph13, %._crit_edge
  %25 = phi i64 [ %23, %.lr.ph13 ], [ %36, %._crit_edge ]
  %26 = load float, ptr %5, align 4, !dbg !46, !tbaa !47
  store float %26, ptr %14, align 4, !dbg !46, !tbaa !50
  %27 = load i32, ptr %2, align 4, !dbg !51, !tbaa !52
 %28 = icmp sgt i32 %27, 1, !dbg !51
  br i1 %28, label %.lr.ph.preheader, label %._crit_edge, !dbg !51

.lr.ph.preheader: ; preds = %24
  %29 = zext nneg i32 %27 to i64, !dbg !51
  br label %.lr.ph, !dbg !54

.lr.ph: ; preds = %.lr.ph.preheader, %34
  %indvars.iv = phi i64 [ 2, %.lr.ph.preheader ], [ %indvars.iv.next, %34 ]
  %30 = phi float [ %26, %.lr.ph.preheader ], [ %35, %34 ]
  %gep = getelementptr float, ptr %invariant.gep, i64 %indvars.iv, !dbg !54
  %31 = load float, ptr %gep, align 4, !dbg !54, !tbaa !47
  %32 = fcmp fast ogt float %31, %30, !dbg !54
  br i1 %32, label %33, label %34, !dbg !54

33: ; preds = %.lr.ph
  store float %31, ptr %14, align 4, !dbg !56, !tbaa !50
  br label %34, !dbg !54

34: ; preds = %33, %.lr.ph
  %35 = phi float [ %31, %33 ], [ %30, %.lr.ph ]
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !57
  %exitcond.not = icmp eq i64 %indvars.iv, %29, !dbg !51
  br i1 %exitcond.not, label %._crit_edge, label %.lr.ph, !dbg !51

._crit_edge:                                      ; preds = %34, %24
  call void @dummy_(ptr %1, ptr nonnull %2, ptr nonnull %5, ptr %6, ptr %7, ptr %8, ptr %9, ptr %10, ptr %11, ptr %12, ptr nonnull %14), !dbg !58
  %36 = add nsw i64 %25, -1, !dbg !38
  %37 = icmp sgt i64 %25, 1, !dbg !38
  br i1 %37, label %24, label %._crit_edge14, !dbg !38
```

This redundant store instruction is caused by passing variable `x` by reference to a `dummy` function.  
In C, function arguments are passed by value by default, while in Fortran, they are passed by reference.  
I confirmed that even in the C version of s314, passing `x` by reference prevented vectorization.

I'll keep investigating, but any advice or comments would be greatly appreciated.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWN2O6ygSfhr6puTIhjg_F33RSU9WR5rdkWZGu5cjYpcd9mDwAk53z9OvCv_ESSc9Z6WNWh0CVR9F1UdRIL1XtUF8ZvmO5a9Psgsn65598iaDNPKIIls-HW358XzQ0tRQSMP4OsAZi2Cd-hMhnBC0ta0HZcCLbMn4nr5Xw3eWgTRlbAmwFfz-2z_38HZSGmE_Qt6Fe3MqBDQEu1-w9JWlL2yV9n8H64KTZujlGQwdcEbnlR0MiaMQP6WFDIwGJl4hY3xvgmrQzyXe45hkfJMxvr3VTUHFcU66w6CqGN-QgmJ8C4s6LOCdWhckNUfKUiisCcp0OEcvpNZQdk3zwfhGlxGf7yXj-yPj-4LxPfUh9cXO2Evd71fgcAM-uerm53702YHxA-zvOKyyDsh2E0aHpUzs-vYeBsfFDsZ38W8LbL0bTRlXn-9Slr8yMQ3McNUQB7GLzT2Y2LyLB6AqiI7Od4rlr8DET72fr4TmE6uridn6dRSbNUePk0-BfArkUyBfAzkbZD_SD8Wx6PARdoJ65OjRz0uoiOaJwTdIzpD8UkkforsXFSS_QYKNConW5waSX1vpPROv_XYYwjFpj6Hi6SJdpLUK5JZTCK1nYghorcKpOy4K2zB-IMzhK2md_TcWYUFaXOZpKYttdUzFUoqtLHCzyqp1hcdVWizFUXKBuSgmfv0uXY2BiReQ0hWn1TLpzHdj30yilenek9p0g-DJoSyhsSVqEm-tV-_90Dfjg9Qay1flaIjxQyvDifFDsIwfVD_M-OGohv2165QuidWVqnuNXWdsG1Sj_sQYJ8Z30nt0QVkz7OWD7UxJKaVUpQwIf9vvYcCWJHZnaq2O5DmK8WFcn8PyJEO_PMYPWdaj_4Yai4Dl_xl2P5nbdDoo0hQvsCCuLdNmtbyZ_CshYJx_6Vp-mAjFOIekKjJIglOtxsfRvSJpVVhtXVIqWRvrgyo8JI1DbYvoiiRGH1pVQNKqItF4Rg28_6F80iqEpKJNkDQynCAJkV1J0XZQo0FHikNfhTJ0DinQtgtaGUxksE2c8rPIeSPvdVdtIl1z3twbM2gNJJUPsvieSOfkh4ekGjZaEs-hpLIu8cGpEm83KCQOve1cgUmp3H0CFORtxg88haSpnGwwaa0yAR0Tr4YmQVlB8ouAxPZZQWtI3qHa5knRtokybTemi0tKiahXuaT4kVzSGyNe4E06o_qmdHXXoKFksu4BGV-D8lBi67CQAUtKzp3HXkLMo0eilNfp1PayQTjiSZ6VdbQ9Y74nDZIKFtDIo0awRn_EbW1do0wNw5aO5PHA8l3yr8vUiY0W5UOy7ZfKxEu2ZuJFkP0OG-m-U2sqIspYQVB2HLsiOLypMpxIMtYoMQga5Rkpy3QmJjgeD5Z8N7mPkJIJeTIEsjWw9R5uP18dcj__9I-vjjmIgHdPkd9P6BA8YuPJkUcECQ7LzpTSBPDBOqQyiaLw7VeonG2gL9eo8gonGaB1eEYTfD9Igq0MAZ2BRobitAAYZ1IeGlWfAs1SyM5jCcePqPHzt_3fgdwClVSaQhcsNPaMkwU-uK7o4_imwmkwSRmDrg-J7YKnjTRWefB2QgMlyghHOmDQhyGCfij7kutV3XURX8YcLHa01NJH3zOeL7RbtKdM9MdFvvijcCr8gWU91WCM5zyP4u1JgVotKfyxd1IaMICiT139uFh9BoULQSLEKgJrK0uotJWBNNpAFMnzWGRoVZuejoxn5bGmr-UAnIWjlLFjPWL2jo5QPf4MsK-8fwwxT-dWri9WKsFnkPwhYp7dIvLpAMr5JgKqomnB14FA-3lIJ_sENFhydKCyXp1EtDyivrh_0To8oSzRXQ_OAnoXt___CeMeV_hy7pRt7P4T3wMYg_VlEcR6tfrsj8sybky_kVx-NuwL6l6vm2g3t1KZ8iydX6jzJwbzK_ZeYG5YfEFYGHwP0yQ3TBbpNMHAvmGTrH5sGpE_Qq6xjdA1BtRIJxGR73a3KHOWTkkTFjW2MXvTMufm3_dyb3z2eBsOcPdJvny4EQmVR9SKWB7PYVuHy9YU2bjg9JFlE-H7PTexRojrn5-tmhFIiC_I8yBt9Lb9ddrIH6eNOcv_wsD7iVlcZ9e5X_P7VLt49FMmTq-wbgh2w_D-lliWYLo3MP7tPpNus9Q88PiuQmFNuTA2XBId_ucRJ3O-_cucN8f8KsF9nVquc95MU7x8qlTufj6HaTmuYaJtfLA4W1UCW6bxGv0H45uRTSOzjDWm03o6RW768hkD54fYetbezNrbOWPT-Y8rLt-bigh-G4DNnG-rCyUudODRwuSGB-JKcX1zzM01Hypedv36KqB8-Sju2fI-1u1Tw6WA-1wbTpUZVfaXso6qOaq8YnKl4pyt0ne2SmnMYYUOTYF04Eka6d9MVilUnYlgU9n4zcCejBwHpluFB-kwTtNPeJa6Q2qUWMlOR673j4HKjI941BdO-HGjOtlzmbV_HXANDlUu1bhjIXx52rLV9C45rvfuMocaGUu4ujYs5u79xvhaa_iO2IIyZ_RB1TLQVYrv4dgFkOYDZHlWBdL9p7BN74U32-mSSuraoQz6A2RLVxxFd5zFU_ksyq3Yyid8ztY8T9NcZKun03O5XVWYrcRRiFwIISuRblKebdZFxqttXj2pZ57yZboRabpJN2K1kMdsnW2yVcZXx7JaLtkyxUYqvaBL4cK6-kl53-Fzlq5WG_4U6ebj4y_nVX9V5Sx_fXLP8dno2NWeLVOtfPAXiKCCji_GfTmev8ZHXUoylBFn17AjRqoND7oUThJwWNjaRAHZc7XnTJR66px-_t8etRg_xEV5xg_Dus7P_L8BAAD__xyKlxY">