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