-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Closed
Description
instcombine takes this code:
define i32 @f(i32 %0) {
%2 = lshr i32 2048, %0
%3 = call i32 @llvm.ctpop.i32(i32 %2)
%4 = freeze i32 %3
ret i32 %4
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.ctpop.i32(i32) #0
and turns it into:
define i32 @f(i32 %0) {
%2 = lshr i32 2048, %0
%.fr = freeze i32 %2
%3 = call i32 @llvm.ctpop.i32(i32 %.fr), !range !0
ret i32 %3
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.ctpop.i32(i32) #0
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
!0 = !{i32 0, i32 13}
but the inferred 0..13 range is too tight. to see this, consider that (in the original code) %2 can easily be poison, this happens when %0 is uge 32. then, ctpop(poison) gives poison, and freezing it results in an arbitrary 32-bit value.
cc @nunoplopes