Issue 89958
Summary miscompilation due to LoopVectorize making a function vulnerable to integer divide-by-zero
Labels miscompilation
Assignees
Reporter regehr
    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

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to