SCEVUDiv simplification


I noticed that our SCEVUDiv does not simplify anything when the RHS is not a constant.
Is that because there is a potential issue with division by zero being simplified?

For instance, would it be okay to simplify:

((%i * %n) /u %n)

into: %i

The way I see it, if %n is 0, then that division is undefined and we can “define it”, at will, as being %i.

Would that make sense in SCEV world?

Maybe because when n is 0, it trap? And you simplification get rid of the trap?

The LLVM-IR says that udiv by zero is undefined behavior.

So, I believe if trap on divide by zero is a required behavior then it has to be tested before in a different way.
Which would make my transformation ok?

Clang adds sanitation check before trying the udiv when compiled with -fsanitize=undefined :

define i32 @foo(i32, i32) local_unnamed_addr #0 {
%3 = icmp eq i32 %1, 0, !nosanitize !2
br i1 %3, label %4, label %7, !prof !3, !nosanitize !2

%5 = zext i32 %0 to i64, !nosanitize !2
%6 = zext i32 %1 to i64, !nosanitize !2
tail call void @__ubsan_handle_divrem_overflow(i8* bitcast ({ { [63 x i8], i32, i32 }, { i16, i16, [15 x i8] } }* @1 to i8*), i64 %5, i64 %6) #2, !nosanitize !2
br label %7, !nosanitize !2

%8 = udiv i32 %0, %1
ret i32 %8

This transform sounds fine to me. Please feel free to send a patch.

-- Sanjoy