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

    <tr>
        <th>Summary</th>
        <td>
            [SLP] Incorrectly swaps arguments of fadd instruction that doesn't have any fast flags
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          igogo-x86
      </td>
    </tr>
</table>

<pre>
    Consider the following IR:

```
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

define double @func(ptr %a, i64 %c, i64 %d) {
entry:
  %a_next = getelementptr inbounds double, ptr %a, i64 1
  %b_next = getelementptr inbounds double, ptr %a_next, i64 %c
  %b = getelementptr inbounds double, ptr %a, i64 %c
  %a_next.d = getelementptr inbounds double, ptr %a_next, i64 %d
  %0 = load double, ptr %a_next.d, align 8
  %b_next.d = getelementptr inbounds double, ptr %b_next, i64 %d
  %1 = load double, ptr %b_next.d, align 8
  %add49.us = fadd double %0, %1
  %b.d = getelementptr inbounds double, ptr %b, i64 %d
  %2 = load double, ptr %b.d, align 8
  %add57.us = fadd double %1, %2
 %sub51.us = fsub double %add49.us, %2
  %a.d = getelementptr inbounds double, ptr %a, i64 %d
  %3 = load double, ptr %a.d, align 8
 %sub59.us = fsub double %add57.us, %3
  %sub53.us = fsub double %sub51.us, %3
  %sub61.us = fsub double %sub59.us, %0
  %result = fadd double %sub53.us, %sub61.us
  ret double %result
}
```

In this IR, we have 4 loads, and they can be paired into 2 linear <2 x double> loads. However, SLP creates vector tree incorrectly for node that consist of these two instructions:

```
  %add49.us = fadd double %0, %1
 %add57.us = fadd double %1, %2
```

That's a result of running -view-slp-tree:

```dot
digraph "SLP: Spill Cost = 0.\nSLP: Extract Cost = 3.\nSLP: Total Cost = 6.\n" {
        label="SLP: Spill Cost = 0.\nSLP: Extract Cost = 3.\nSLP: Total Cost = 6.\n";

 Node0xaaaad92dfcf0 [shape=record,label="{0.\n  %sub61.us = fsub double %sub59.us, %0 \<extract\>\n  %sub53.us = fsub double %sub51.us, %3 \<extract\>\n}"];
        Node0xaaaad92dfb40 [shape=record,label="{1.\n  %sub59.us = fsub double %add57.us, %3\n %sub51.us = fsub double %add49.us, %2\n}"];
        Node0xaaaad92dfb40 -> Node0xaaaad92dfcf0;
        Node0xaaaad92dfea0 [shape=record,label="{2.\n  %add57.us = fadd double %1, %2\n  %add49.us = fadd double %0, %1\n}"];
        Node0xaaaad92dfea0 -> Node0xaaaad92dfb40;
        Node0xaaaad92f91e0 [shape=record,color=red,label="{3.\n\<splat\>   %1 = load double, ptr %b_next.d, align 8\n  %1 = load double, ptr %b_next.d, align 8\n}"];
 Node0xaaaad92f91e0 -> Node0xaaaad92dfea0;
        Node0xaaaad92f9390 [shape=record,color=red,label="{4.\n  %2 = load double, ptr %b.d, align 8\n  %0 = load double, ptr %a_next.d, align 8\n}"];
 Node0xaaaad92f9390 -> Node0xaaaad92dfea0;
        Node0xaaaad92f9540 [shape=record,color=red,label="{5.\n  %3 = load double, ptr %a.d, align 8\n  %2 = load double, ptr %b.d, align 8\n}"];
 Node0xaaaad92f9540 -> Node0xaaaad92dfb40;
        Node0xaaaad92f9870 [shape=record,label="{6.\n  %3 = load double, ptr %a.d, align 8\n  %0 = load double, ptr %a_next.d, align 8\n}"];
        Node0xaaaad92f9870 -> Node0xaaaad92dfcf0;
}
```

After forcing vectorization (opt -S -passes=slp-vectorizer  IR.ll -slp-threshold=-7), we get the following code:

```
define double @func(ptr %a, i64 %c, i64 %d) {
entry:
  %a_next = getelementptr inbounds double, ptr %a, i64 1
 %b_next = getelementptr inbounds double, ptr %a_next, i64 %c
  %b = getelementptr inbounds double, ptr %a, i64 %c
  %b_next.d = getelementptr inbounds double, ptr %b_next, i64 %d
  %0 = load double, ptr %b_next.d, align 8
  %b.d = getelementptr inbounds double, ptr %b, i64 %d
  %a.d = getelementptr inbounds double, ptr %a, i64 %d
  %1 = load double, ptr %b.d, align 8
  %2 = load <2 x double>, ptr %a.d, align 8
  %3 = shufflevector <2 x double> %2, <2 x double> poison, <2 x i32> <i32 1, i32 0>
  %4 = insertelement <2 x double> poison, double %0, i32 0
  %5 = shufflevector <2 x double> %4, <2 x double> poison, <2 x i32> zeroinitializer
  %6 = insertelement <2 x double> poison, double %1, i32 0
  %7 = shufflevector <2 x double> %6, <2 x double> %2, <2 x i32> <i32 0, i32 3>
  %8 = fadd <2 x double> %5, %7
  %9 = insertelement <2 x double> %2, double %1, i32 1
  %10 = fsub <2 x double> %8, %9
  %11 = fsub <2 x double> %10, %3
  %12 = extractelement <2 x double> %11, i32 0
  %13 = extractelement <2 x double> %11, i32 1
  %result = fadd double %13, %12
  ret double %result
}
```

Here's some mental debugging to see what we have in %8:

```
%2 = {a, a.next}
%3 = {a.next, a}
%4 = {b_next, poison}
%5 = {b_next, b_next}
%6 = {b, poison}
%7 = {b, a.next}

%8 = %5 + %7:
    b_next + b
 b_next + a.next
```

As you can see, in result, arguments of **%add49.us = fadd double %0, %1** got swapped, which is not correct since there's no reassoc flag there.

This example is quite complicated, but unfortunately dropping any part of does not show this error.
 

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWV1v4zrO_jXKDeHAlj-SXOSiTaY4AwxeDE7P_QvZpmPtqpJXkpv2_PqFZDtxUidNOrPAGXRSxxKp56FEimSZMXwnEdckfSTpdsZaWyu95ju1U8HbMpvlqnxfb5Q0vEQNtkaolBBqz-UOvv9J4gcSbkk4fGZh_-O_WqZ3aKFklgn2rloLJN4CoRSDFxI_YMCXJH5w_2Ma8Cgj8YP_cN-yhMQPWRLwiLoJEV0GMqbdu2f3jtKTRazmjcBhAcZ0UWdJ0Mp_S7WXgeCyfQt2sj2IdZ8lVlwilKrNnXASVq0sCF02VgOhKSN0AzxL3HMxei4JXQFZPHZKUFr9frAEeMH_l_jW0d2hRYEvKK1TymWuWlmafkmn83ytaKQn_4IeL3ICfKTva5DOtHRLzMtfw1WONIZelVCsvCQ4L90rJvhOwvKDhe7Ekl_DEl3Bkl_FwsoyWc1b4xVUrCwPB4umoRNx2sfY74V9ATG9hvgK2HRxAWzUg-19xT2aNk-jw3TT5qPpA-8zKT907ym5QDG-dkCmKPaQV5che_Y95Hi0lBOLL4gNVpgWyy4ZaEDSi4UjMY2mFXZqEwYcvdCgf5DVLrIeJndq-tC22E6G4-7zuwRbc-OCN93AHqFmrwiJt61fi8nSxfl3KJiEHKFhXGMJXFoFFASXyDSQeEPhbdiL-FsnPoc_1B5fUTs9zz9-QqGRWTTwioVVGqxGBC4LpTUWVrxDpTRIVSLYmlko3DVjLKjKATAIdq-AS2N1W1iupLl-3dztg_d5waQ1_6qZJXRhgEG_k6oC3Urp7sfgleM-MKIJHPFL4EvV71vJd5o1tbu_nn_8JPEDPDdcCNgo0x2QcE7SjezHvr1ZzQp7HI3Ho38py0aSmR8jlB5vLej_CZajIPH2f7kqiR_H1OH_VInhG2OMlStaVkUVAkkfTc0aJPFWY6G0c-kRNLJ47HDc7WtA0g2JN9gB91--jRXd7OuXFDl3o5Sk2wPLwbRnNPPkFprRCc3bA5gTujdO34s-cJ7-cfM-E0V2C3F6JH6bV45m3-Dy93B1gKe45sknXKtVhNNcCyWU9i8-Mu98qDtephGsP1zwpXRksMoX5CbsM8FuyjDIPjVMvLrfMMnxSNyR4wwi9yaVN1nA0fiiBdIL_n_NAunRAnekQF8z2ufk0wsx4Aa_WC5uiQHZL9H9PRt-Gf9n4e964vVQWdQu4ylcbtBlRPxv5hIbIHSpGgvBMwQNMwYNibcubxhmoQb4_udcCOjSiVqjqZUoSbwNFoSu-lTOF8InJXqhyouJxz-_BP7HVsC_v-q8dnavV52_q4r8XaXa1YvnEolRpDovLT6r9I7BwtRtVQnsi40PJYpPGlw6cD7QKG6UHA3xmHqBeMNjCj7jcA-hQ3NcNPGLcmlQDxa7pvssKekUHrWlN1JI7qLwN2rFJbecCRdFRutlX0UfTaFf3Ig-m0R_tjOn5j9YKz41__KY700pTPvMbzESWd3CeQAzwXjcvInCY4o9pWPZr78ay0TXZaJworEQdb7R1x3XYEeTWxPF98tHN3UoonjIrumvdiX-QI2-jjbqBcEhZAJKzNvdzl1jVoFBhH3N7KFlwWVn5qu32yG0kMWjD1hs7oPwAcwQO9z4fIjPbDyeDOPH-N27xWhS-nFS_zSalB0mTStZnIyfIx1mLfsmt1uTPnZH_HjzAgw3Jn2EvH87etVrvZKmGHhXrW_-GPSxm8u-t-FR6V3rtseAqoDQB_9zYwnmZ8NOWTB71jQ-3YV9zYsauAGpLPSdITBcFuhSmf5USAUamTGqgEqwXTcyP23EcAP4xl4agU7bf1puEQr10gheMNutlbcWWlkpbVvJLIp3KLVqGnfCmHyHhmnfvykVdnBMrfZdtwy1Vno-pCX-16xcx-UqXrEZrqNsGS_DVbZazur1Kk6zRbGMMKGrIs8wWuIyKfOsCvOowFUy42sa0jhMoyiiaZIu5wlmFEMWruIwiZJFRpIQXxgXcyFeX-ZK72bcmBbXGc3SxcynzMb_xYZSiXvwg10aO9NrJxPk7c6QJBTcWHPUYrkV_k89zz9-knQL30etOLcl5nR7_UaO-m9dl85ZRxK6sJ0bOsNVzFi_MWbWarGurW18r44-Efq047Zu83mhXgh9clD6X0Gj1b-wsIQ-eQKG0CdP8L8BAAD___D2kWA">