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

    <tr>
        <th>Summary</th>
        <td>
            miscompilation due to LoopVectorize making a function vulnerable to integer divide-by-zero
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation
      </td>
    </tr>

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

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

<pre>
    https://alive2.llvm.org/ce/z/Kx2anL

this function:
```llvm
define i64 @f(i64 %0) {
  br label %2

2: ; preds = %5, %1
  %3 = phi i64 [ 0, %1 ], [ %6, %5 ]
  %4 = icmp slt i64 %3, %0
  br i1 %4, label %5, label %9

5:                                                ; preds = %2
  %6 = add i64 %3, 1
  %7 = udiv i64 42, %0
  %8 = icmp slt i64 %3, %7
  br i1 %8, label %2, label %9

9: ; preds = %5, %2
  %10 = phi i64 [ 1, %2 ], [ 0, %5 ]
  ret i64 %10
}
```
is getting optimized to:
```lllvm
define noundef i64 @f(i64 %0) local_unnamed_addr #0 {
 %smax = tail call i64 @llvm.smax.i64(i64 %0, i64 0)
  %2 = udiv i64 42, %0
  %umin = tail call i64 @llvm.umin.i64(i64 %smax, i64 %2)
 %min.iters.check = icmp ult i64 %umin, 4
  br i1 %min.iters.check, label %scalar.ph.preheader, label %vector.ph

vector.ph: ; preds = %1
  %3 = add nuw nsw i64 %umin, 1
 %n.mod.vf = and i64 %3, 3
  %4 = icmp eq i64 %n.mod.vf, 0
  %5 = select i1 %4, i64 4, i64 %n.mod.vf
  %n.vec = sub nsw i64 %3, %5
  br label %vector.body

vector.body:                                      ; preds = %vector.body, %vector.ph
  %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  %index.next = add nuw i64 %index, 4
  %6 = icmp eq i64 %index.next, %n.vec
  br i1 %6, label %scalar.ph.preheader, label %vector.body, !llvm.loop !0

scalar.ph.preheader: ; preds = %vector.body, %1
  %.ph = phi i64 [ 0, %1 ], [ %n.vec, %vector.body ]
  br label %scalar.ph

scalar.ph: ; preds = %scalar.ph.preheader, %9
  %7 = phi i64 [ %10, %9 ], [ %.ph, %scalar.ph.preheader ]
  %8 = icmp slt i64 %7, %0
  br i1 %8, label %9, label %13

9: ; preds = %scalar.ph
  %10 = add nuw nsw i64 %7, 1
 %11 = udiv i64 42, %0
  %12 = icmp ult i64 %7, %11
  br i1 %12, label %scalar.ph, label %13, !llvm.loop !3

13: ; preds = %9, %scalar.ph
  %14 = phi i64 [ 1, %scalar.ph ], [ 0, %9 ]
  ret i64 %14
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i64 @llvm.smax.i64(i64, i64) #1

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i64 @llvm.umin.i64(i64, i64) #1

attributes #0 = { nofree norecurse nosync nounwind memory(none) }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.isvectorized", i32 1}
!2 = !{!"llvm.loop.unroll.runtime.disable"}
!3 = distinct !{!3, !2, !1}
```

the problem is that the optimized code can divide by zero even when the original code doesn't. to see this, pass 0 as an argument to `f`. I also independently verified on an x64-64 that the optimized code traps out with an FPE while the original code does not. it's LoopVectorize that's the culprit.

cc @nunoplopes @hatsunespica

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWM2S4ygSfhp8ySiFhCTLPvhQ1bWO2Ng-7GmvHRhSFtsINIBcVf30EyD_SLJcUzMxh-nosA1kJl9mfmRCMefkUSPuSPlCytcV631j7M7iERu7OhjxsWu87xzJnwndE7pnSp6QJkqd2sTYI6F7joTufxG6_887Zfo7SV9J-jx8-kY6qHvNvTQ6mBjW1unwPxgZpgTWUiPIdQGkSGtCN_EnLVNCt0Cql0EM4GBBsQOqsEbHW1GSPwPJX6CzKByQ_DWIlIR-C9_ZRZ_QMo-LXSOH7coXSC9SQMrX-Lt8CeP1eb6M8zcLRbQgeduBUx7OUPOzdDrCKrMoH1ausMvJaDt2ogxO_Ml_dz7TEdJ1nGRCTECOo1FFiV7IUxQp6NwLQsvNp_5Wd_5uJh7Sx_5uP03a2JEsvctadhEbZy1dSpnFK-js7BepXmdkHIbSwRG9l_oIpvOylb9QgDdL3J2TV5teC6wfkVgZztSPXmvWovjBhLBAaJ6OyE1o6Vr2Hh31TCrgTKmLuXjgwnIi18XE9LcoEvYYxYt-Ia19K_Unm4Xl6WZh-8t-Q2K3N-hR2qN1CW-Q_7xRpr9RJpgMBoo7ysy0J5RxnClmk65JOosNMoF2sn5C7k1YH1PrNrlEsft6EM6I7t9Au7c52uzmpE5aI5JTPajo6bHKl0sE_naRumgH4XEiyijsUCH345IRMzcK-FX_pqqTE_JBvT-MwV9OZ7lUOc_BCeV9IWZx-quF6C60YyMDhFl-Im6pBb4_LMRXjVlBjlqJxnc_FQybzWr0TXSS3nN04uqEiddiOcvZ3ZYx4nf8Xf8Vxt5ilMUTp4zpwiAdJ2XJ1hKl7-M-JnmM5Rfb3uDhpwEek-kKcBH1ItYH8bm1h1FrGiMeCvhZcoY67DWsLFifkWO5oVUPG_hm1sLGoyz_4442C9G4oy3UnWpWdLLsC8U8o4sV9-JTlt05ldFlzs69WyDoxOUsX_R5O8_GGGzxsJtfxZe6-vZRVy_mXX34zF9gf759wrP3NlxjQYdGrA6M_wRtaouhc7sPzWMDf5NagOuQ94p5dlAIb1Ipi763Glpsjf0gdKONxmvzE8gVs_hJoz6X8HiVpXn2z4A4be-fQGTeW3noPbrzhSXkt3q5IbPIe-vuMc6xwDU9U5PZyOTf5TfMqUDP501I56XmPtA4XL3opaBkZwZm9KZKz0fvKksovR6ERLqhOoY7IqHxNMmcQjbWp5_o99oapRLbay9bTIR0watgaWQgf4A6v6K9oH9wo728xBA6aw4KW5AOfMM8hLnbJZcbgcCZBiFPUiAcPuAXWgN4Qg1vDepB3sqj1EwN4sKg04RWPgFvwCFCePEFRB1zDlJgDpgGZo99i9oHIbJOa7JOE_g3MOUMhP7aoRaovfqAE1pZSxRgdFB8XxdP6-IhWm9Z58D0Ht6kb4LC_r__grdGKnwAFrTxCUhPaOXguzHd_y4ZjJvE6aDJe9VZ6ZNxCDkPZ0f32nTKdIG6Rdow73qNrpOcDVIrscvFNt-yFe6yKsu3m5RmxarZ8YpVXBQ0ralIGdb1pubbdZaJel1vaVWt5I6mtEgLWmRVvi7ThNb5BsuDyDKGNN9uSJFiy6S6Pr5X0rked5vtttysYsl28R1PaSsdN20nFYsvb0rD297uguLToT-6UASk8-5mykuvcDfVA9FjyNk0UC37GZ5H7Pqwh1OvNNp4JH3IqMcj2jOPng4fT4FHq96q2Z8SjtI3_SHhpiV0H59Tw9dTZ83_kXtC99FBR-g--vh7AAAA__8GEKah">