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

    <tr>
        <th>Summary</th>
        <td>
            Inlining applies overly-broad function return range to inlined intrinsic
        </td>
    </tr>

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

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

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

<pre>
    Found investigating https://github.com/rust-lang/rust/pull/133984

Given this IR:
```llvm
define noundef range(i8 -1, 3) i8 @rust_i16_partial_ord(i16 noundef %0, i16 noundef %1) unnamed_addr #0 {
  %7 = tail call noundef i8 @llvm.scmp.i8.i16(i16 %0, i16 %1)
  ret i8 %7
}

define noundef zeroext i1 @check_lt_direct_before_inlining(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 {
start:
  %_3.i4.i = tail call noundef i8 @rust_i16_partial_ord(i16 %0, i16 %2)
  switch i8 %_3.i4.i, label %bb4.i [
    i8 2, label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"
 i8 0, label %bb5.i
  ]

bb5.i: ; preds = %start
  %_0.i.i = icmp ult i16 %1, %3
  br label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"

bb4.i: ; preds = %start
  %4 = icmp slt i16 %0, %2
  br label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"

"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit": ; preds = %start, %bb5.i, %bb4.i
  %_0.sroa.0.0.i = phi i1 [ %_0.i.i, %bb5.i ], [ %4, %bb4.i ], [ false, %start ]
  ret i1 %_0.sroa.0.0.i
}
```
Today <https://llvm.godbolt.org/z/Wj8cPnK3n> it optimizes to 
```llvm
define noundef zeroext i1 @check_lt_direct_before_inlining(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 {
start:
  %4 = tail call noundef range(i8 -1, 3) i8 @llvm.scmp.i8.i16(i16 %0, i16 %2)
 switch i8 %4, label %bb4.i [
    i8 2, label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"
 i8 0, label %bb5.i
  ]

bb5.i: ; preds = %start
  %_0.i.i = icmp ult i16 %1, %3
  br label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"

bb4.i: ; preds = %start
  %5 = icmp slt i16 %0, %2
  br label %"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit"

"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$2lt17h933a2b8cae739748E.exit": ; preds = %bb4.i, %bb5.i, %start
  %_0.sroa.0.0.i = phi i1 [ %_0.i.i, %bb5.i ], [ %5, %bb4.i ], [ false, %start ]
  ret i1 %_0.sroa.0.0.i
}
```

Note, in particular, the inlined intrinsic call at the beginning:
```llvm
start:
  %4 = tail call noundef range(i8 -1, 3) i8 @llvm.scmp.i8.i16(i16 %0, i16 %2)
```
That's an overly-broad range for `scmp`, which is always in [-1, 2).

As a result, follow-up passes don't optimize away that dead `i8 2` arm of the `switch` -- I guess they trust that range and don't look at what they know `scmp` *actually* returns.

So it would be good if either:
1) inlining was smarter about the output range it put on a known intrinsic like this, or
2) some pre-inlining optimized put the correct output range on `scmp`, as
```diff
 define noundef range(i8 -1, 3) i8 @rust_i16_partial_ord(i16 noundef %0, i16 noundef %1) unnamed_addr #0 {
-  %7 = tail call noundef i8 @llvm.scmp.i8.i16(i16 %0, i16 %1)
+  %7 = tail call noundef range(i8 -1, 2) i8 @llvm.scmp.i8.i16(i16 %0, i16 %1)
 ret i8 %7
 }
```
also fixes the problem (<https://llvm.godbolt.org/z/h7a55WKxK>).

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWF1v2zYU_TX0y4UFiqQs-8EPSlIXRYcu6DoU2ItBSZTFhiIFkorj_vqBlJzYSZtl2Na1QIEAsfhxP849PFcUd07utBBrlF2g7GrGB98au3aV8b6rullp6sN6YwZdg9S3wnm5417qHbTe9w7RApENIpud9O1QJpXpENnYwfm54no3_UZk0w9KIbJJKV0tGcIFwsVreSs0-FY6ePM-GMIFWuDxT6nbDuGiFo3UAnRwLxqwXO8EIku5hHmKyCVQRFYgl4AYDn62Ml1se2695GprbB2Wpov77YhkOOx6NJYGI4PWvBP1lte1BUQoBpRfIFxAWJEDolfguVRQcaXuN4-eQ6yJq7o-kctEpovJ66m3yUu0Z4WPG0mWh4zzqxGNR6l-FtaIOw8yDS6qVlQ3W-W3tbSi8ttSNMaKrdRKahlgfmGeT8bIF8boc3g4z60fixWh2dJEskQ-C9AzpXkEEjmC5PbSV-2E0-QjrFO8FCqMlWX0mo01grCSnC1AhGz_eMcqY0Xmh16JRbZFhP3yAREmu14hwgaCEYkrkiSUL7ke4_s1hDfNNsbe_w7brxFhvyPCLhFhwdT763HidXggyqd5u6KUk3JZcZHTVc6WrxJxJz0iJIQql4AfJZIlckQzm6gwDtECEL2A3oraRXgRyUb0j9DjRE7Iy6rrYVD-hGyXYynD2tJ-77DEpNlLkmYP-bqHfPGUL_lx8v0eA_s6-iO8IzGPv9mRt5GKzhqe4ARPjOxbGbUru3ig6qmVyPbwPC5gp1ZP5xqunJgmYyjTMZl0NH3i_UFTj70E4eKDqfkBEL08b1pRuXemLo3yibGhXX1GZPPx07K61m-pRvQVSA-m97KTn4UDb-Cvu9SPIt3sK6L9XJd9Wa87yviZirOf-v1Tv7Psp35_W_0e6_JUvx9T8Z_pd_bf6jfCxTvjox2pIb5GVoPiNgz4VkBUUxFuKN5K7WQ1Khr3cbYUO6mj2H7xkvHNdfGsM7XcI5I74BrMrbDqMC-t4fXoDRpjAS1wsBzWk0vYtzJIqgOu9vzgAh4ouxgDCvaTEa7CAQcr3KBi826MUmY_H3rouXPCQW00IvlDbwO-5wfwLfdQC14Hp1GSFxi47cA0EckQStT0MD6fwxvYDcK5MHcAH97zRxNj8FzX936UMTehHvt2LMoBbrTZn-QGiBS88gNX6oBIEegxWO2mdH4zoRHvzaBqKAXsjKlBNiCkb4Udaxevcce2CnvuwHXcemGBl2YYmWAG3w_H8KSH8GA08BiMPqGPkjciXk0DeMYiXARswZlOhOM1v_dzxK-OtoKPytjQ6M99Gf2ojNydEqGWTRPo9__fd-f_9oUXkYtnTT7JkfzdU3W8WZ9frOGpinDlDDTyTkTCQm9NqUQHiCxf-mbY5jzLPr69e4voq-mszeo1rVd0xWdineYsJauc5ItZu07LktYsL5uG8YyUVSOaJseMZoJxxsp6JtcEkwxTvCApS9NFkuarpl4ul4zyioqcIoZFx6VKYjTG7mbSuUGsU4rTfDWLPdLF7zaEaLGHOBv6QHY1s-uwaV4OOxeAlM67BzNeeiXWb44c5n2vpHDn-tMMuvLS6OkgTjz25qnWzgar1s98DYoyO_6b99Z8EpVHZBODdfGTUMzmdk3-DAAA__-0YVDl">