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

    <tr>
        <th>Summary</th>
        <td>
            llvm.smul.with.overflow.i64 lowered to non-existent __multi3 on PowerPC 32-bit
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:PowerPC
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          aaronpuchert
      </td>
    </tr>
</table>

<pre>
    LLVM 14 built with Clang 14 doesn't link on PowerPC (32-bit) because of
```
/usr/bin/ld: LoopStrengthReduce.cpp:(.text._ZN12_GLOBAL__N_111LSRInstance24GenerateAllReuseFormulaeEv+0xf1c): undefined reference to `__multi3'
```
The relevant lines are
```c++
    int64_t NewBaseOffset = (uint64_t)Base.BaseOffset * Factor;
    assert(Factor != 0 && "Zero factor not expected!");
    if (NewBaseOffset / Factor != Base.BaseOffset)
      continue;
```

We can build a small reproducer for that:
```c++
bool mul_overflow(unsigned long long a, long long b) {
    long long prod = a * b;
    return (prod / b != a);
}
```

Clang 13 compiles this to (with `-target powerpc-unknown-linux-gnu -O2`):
```llvm
define dso_local zeroext i1 @_Z12mul_overflowyx(i64 %0, i64 %1) local_unnamed_addr #0 {
  %3 = mul i64 %1, %0
  %4 = sdiv i64 %3, %1
  %5 = icmp ne i64 %4, %0
  ret i1 %5
}
```

So basically what it says. But Clang 14 recognizes that this is basically an overflow check and that we can get rid of the superfluous division:
```llvm
define dso_local noundef zeroext i1 @_Z12mul_overflowyx(i64 noundef %0, i64 noundef %1) local_unnamed_addr #1 {
  %3 = tail call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %1, i64 %0)
  %4 = extractvalue { i64, i1 } %3, 1
  ret i1 %4
}
```
Then CodeGen produces this:
```assembly
_Z12mul_overflowyx:                     # @_Z12mul_overflowyx
.Lfunc_begin0:
        .cfi_startproc
# %bb.0:
        mflr 0
        stw 0, 4(1)
        stwu 1, -16(1)
        .cfi_def_cfa_offset 16
        .cfi_offset lr, 4
        mr      9, 3
        srawi 3, 5, 31
        srawi 7, 9, 31
        mr      10, 4
        mr      4, 3
        mr      8, 7
        bl __multi3
        srawi 5, 5, 31
        xor 3, 3, 5
        xor 4, 4, 5
        or 3, 4, 3
        cntlzw  3, 3
        not     3, 3
        rlwinm 3, 3, 27, 31, 31
        lwz 0, 20(1)
        addi 1, 1, 16
        mtlr 0
        blr
.Lfunc_end0:
        .size   _Z12mul_overflowyx, .Lfunc_end0-.Lfunc_begin0
        .cfi_endproc
```

But there is no `__multi3` on 32-bit PowerPC, because it doesn't have a 128-bit integer type. It's not in `libgcc_s.so` and compiler-rt also shouldn't have it: `compiler-rt/lib/builtins/int_types.h` has
```c
#if defined(__LP64__) || defined(__wasm__) || defined(__mips64) ||             \
    defined(__riscv) || defined(_WIN64)
#define CRT_HAS_128BIT
#endif
```
and then `compiler-rt/lib/builtins/multi3.c` is guarded with that.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVV9tu4zgM_RrnRYjhW24PeWjT7W6BbGcwHewA82LIspxoq0iBJCdtv35J2U6cxFPMBoadiBRJHR6TTKHL9-V6_c_fJM5IUQvpyFG4LVlJqja4VmpuVZDMHJFCvRKtyFd95ObrigTJPE3GhXBBsiAFZ7S2nOgqiB6C6C6YRu3V_Ewea2vgXggw9ijLIL0ja633L85wtXHbb7ysGQ_Zfg8SsBw6_ubC_OdznOR_rr_c363z_DmP43j98u1JWUcV40n2J1fcUMfvpPzGwf2jNrtaUv7HIUjuo7cqZhAbuqpVySuheEkMrzi4ZJw4TSC-PIcdTqRwxMHIv2857JH8QJWHgFtCDb9SBTf3ePlVAh-h3DTLHXnmx3tq-ZeqstyRIH1A1OpWCrGhMOxrJHfkkTKnTZD2zFFruQH9eSMDtRhtRfBlChc8kp_caFI1YqUd4W97zhwvUTVJPAz9-CoM5Cq65JFc2r-KDo2cLBDCtHJC1fxk-Drn_v6DE0aVp1ZJKLE7KiUAujcaE25IBe7cljpM-yegFlpLApnK9YGbSuoj4qis2GBOpQau-hsNklXvZ4HUDGa9g59lGIHPCPWoFxf4GO5qoxCjRg2gKTpUaB_MYPbwyeHbtygFrHZ7IYE7biusZ14y9-8ZbBg7ajaA_x7fqz0b1-pV6aMaA9nqt_FG1WT8JUHDnspX3qQ87JqlhuCktDqXmlFJPoAR8BIREZMgi_KfcdLH7_0NQhDTDCKZRIha-z1GyLyBvFaK7niZ07JESqRRH0pQTT18YLS3d9XYOytlXsmW4tBppa1W3NOaeC3BdnsCZ2gVs2tzkBV_GtD_HfRfNCmoFXAU-U6OwDEiHLH03YbkvnbnEmc40xslPnx6QMvnCK7zZiBwhxthW85eYaVslI8NvzGBRpRQ_2CZE1vvUb3WtSVwdGGFVv8reUr7kvW7SezU-8nsrX2S1HgwqY4KSfDsKEVr3ijqPmAcGHhoIZIQSRx24YRecd5nw5lhixtSwLkM1JsDlTUf8tNSJb5Nf_Z5-qFmK7LSJYf-QNpK07x6tznA0ror5HuzPABw2pa7qw9A94uMeEPhuqoVywu-ESo6ee02h6wSOTQx4yA61rXIFI9WFOGt_q6ShkSXa9Ydic81Qh5f1WYvrolPwTieDmr4IIAgOatorpseAKq3Oq1MmsbbZWSmeS5Qll6FYOhREJ_DiRfHQ_IZihZD8s52HH3iOBtw3MnmKJtdygpJTi1_IJrJL6N9g0aVNs68yo0wa5NxI-w2DoXKlJMfR9JZvpBhG8fPkMzIo1C7XkDJrA16IHR5_GiokkSDTIBaIBquNLcrEuzcLfsKYEOf6FyVAzS3UFThOVS2VqS3c3z5utxSEJR6b8pQsceKDpXXcKzc6nK0m0Y4tzbDaje-YgTd0Aqr5zF3Sw8cZoI4mXt1mNX4BuYU977nIXmCIWhmfWaEQh9SFBvGchtajW6wLbS93oyNI1RaTexW17LsWRc47eDunipOxaLACRmHcKEsfAXfOfq14RaNb6m9GZG60gEDXTvhQobzfP0VBsy8mX5WcF0Ij9Tufincib3FMnwS9j_BZHVOTn-XEZYdhi3-eHr29k6htr1u9e17_tfdSw5A3z99P0kh02L4P0TTcrn6DeCavIcMUQM6bGpqSpgT_cSFXTsclcu0XKQLOnLCSb78pKFB3wTCwG6Y2pRWY_4mrOPwZ6CjV_8_UcOxUW3kcuvc3veb5BGuDZitixDixnix7zePMdD6XxjUMdvW1hyjn2TZNBptl1lFI5oVrOQ8ZmxWTVJGF5MoSatZVVbVZCRpwaVdBhOYk5OCslcADzyeGJ4Ek4eRWCZRkkRpvEjidB7Pw-kCmkzM0zSN5kmcTaCL8R30-9CDoM1mZDwe46LeWGz2cF57FkLDxKmbe7dgn9Zuq82SUqPVvobpyLiRP8rSn-M_1osPeQ">