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

    <tr>
        <th>Summary</th>
        <td>
            Is CMN safe when the subtraction is nsw?
        </td>
    </tr>

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

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

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

<pre>
    In C, 

bool cmp(int a, int b) {
return a > -b;
}

yeilds

define i1 @cmn_nsw(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK:       // %bb.0:
; CHECK-NEXT:    neg w8, w1
; CHECK-NEXT:    cmp w0, w8
; CHECK-NEXT:    cset w0, gt
; CHECK-NEXT: ret
  %sub = sub nsw i32 0, %b
  %cmp = icmp sgt i32 %a, %sub
  ret i1 %cmp
}

Now, because no fwrapv, the sub is assumed to be nsw.

However, this would mean no signed wrap.

For 0 - b to be signed wrap, b would have to be a value that fits in the realm of possible signed integers, and cause a wrap.

The only value for b that fits is 0x80000000, and therefore:
Iff b is 0x80000000, then 0 - b is signed wrap.

Therefore,
if 0 - b is not signed wrap, or nsw, b is not 0x80000000

Which means in theory I could do this:
define i1 @cmn_nsw(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK:       // %bb.0:
; CHECK-NEXT:    cmn w0, w1
; CHECK-NEXT:    cset w0, gt
; CHECK-NEXT:    ret
  %sub = sub nsw i32 0, %b
  %cmp = icmp sgt i32 %a, %sub
  ret i1 %cmp
}

However, alive2 says:

define i1 @src(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK:       // %bb.0:
; CHECK-NEXT:    cmn w0, w1
; CHECK-NEXT:    cset w0, gt
; CHECK-NEXT: ret
  %sub = sub nsw i32 0, %b
  %cmp = icmp sgt i32 %a, %sub
  ret i1 %cmp
}

define i1 @tgt(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK:       // %bb.0:
; CHECK-NEXT:    cmn w0, w1
; CHECK-NEXT:    cset w0, gt
; CHECK-NEXT:    ret
  %isNotMin = icmp ne i32 %b, -2147483648
 call void @llvm.assume(i1 %isNotMin)
  %sub = sub i32 0, %b
  %cmp = icmp sgt i32 %a, %sub
  ret i1 %cmp
}

ERROR: Source is more defined than target

Example:
i32 %a = #x00000003 (3)
i32 %b = #x80000000 (2147483648, -2147483648)

Source:
i32 %sub = poison
i1 %cmp = poison

Target:
i1 %isNotMin = #x0 (0)
void = UB triggered!

I know I am thinking of multiple levels at once, but the question is, if I am checking if it is safe to turn cmp into cmn, is it safe to just look at the no signed wrap flag?
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcVsFu4zYQ_Rr6MrAhkZYtH3RwnBhrdDcF0hQteikoaSRxQ5EuSVnJ3xck5cTJJuipi8XqIoJ882bmkZwht1a0CrEg2RXJrmd8cJ02xfYvNDpls1LXT8VBwY7QHZBkS5JtqbWEqj8SmgvlgPsVPygJ3QBZX5Fka9ANRgEHwm5gXhLmJ8n6OhI8oZC1jeMaG6EQRApkmVS9-lvZ0RMzCoRmkTuOL-gJu4Ldp5vdL_PP26ubz4Rt4WzKtpfrfiV-hO4J3QeecpG8gc1vb_68n7AKWxhz73dMP8JU_RHGJGDyDzEW3QRq3bsgg37eh5bZoQTCrsH_lR1DysE05D2BvFcPEn5gWweXIkWSADXogp7B4lL3Wz16aIkVHyyC0tCMhh9PftJ1GLwLC9zaoccanIYSfTiLaP5Jj3hCE9HCwqgHWUOPXHmqcIpq8IQTfq8NJDCHcmK6QIQwJoKOn3BCcDhxOSC4jjtohLMgVIjMIJc96AaO2lpRymcyoRy2aKwn5KqGmBm_DOO-Q9BKPk3cjTY-ohcPFpLHPInfmcZ1aLDRBuNBOTQNlN8iXYdqylDYdwS4f2ahO5JsRfMCVtq91UMbCGd_94K4cBcI_-hE1QXFz8po8wQHqIKQtQ77EkP-4e5V1avznfn4Xv3nnQH4_tfm4txzKU5IwfKnSea3SltT_QQqf3eJX2noWvcTaPj6pAp7q90XoV5k8uk-p7WDOU2X62XOVkvfUaDiUsJJi9oLIuWpX8Sq7IVJLwkJ3by3Vf_PNt3c3f1655P7TQ-mQl-mem0Q4vb5sskVOG7akLg3eOT9UU5V9OwtxEAoe5xqGwNCcxYTOUvyjDkXQI-5kOiNYsGWJNsY1yt3Z1WOWlit_Hx6qcXztK_XMfJonX6zbSFkH0cS_cXtYdfw-xU4I9oWDdaEppHsAA9Kj3AA3vuyrB6Ean0H6wfpxFEiSDyhtMAdaFVhqPuDC93unwGtE1qBCH1NNJGl6rAKLKIB4ULL4U1oneGx5TMSyml_foOZ9agz5OtgHUitH7xD7-R1y4ZG8paw_awuWL1hGz7DIl0v82WW04zNumKzWpd8RVdVs642K8oxS6psVeYsT9OKrfOZKGhCsySjeZpnScYWq6ysNyxLaM3z5SYvyTLBngu5CMdZm3YmrB2wSJdpTulM8hKlDa9QShWOEFYJpf5RagpvNC-H1vr7IKyzLzROOInFwcLuy23Md_SNeXrROMOrSczQX9l-NhhZdM4dQw0PVaEVrhvKRaV7QveeePrNj0Z_xcoRug_hWEL3U7yngv4bAAD___ipKA4">