This patch extends r217953 to handle unsigned comparison, which requires special handling due to unsigned wrapping.
I believe this is safe, but kicking off full correctness runs now..
Chad
Differential D5526
[IndVarSimplify] Widen loop compares for unsigned IVs that have a uniform step of one. mcrosier on Sep 29 2014, 9:48 AM. Authored by
Details
Diff Detail Event TimelineComment Actions That looks safe. Why do you need to check unit stride in the unsigned case but not in the signed case? Can you think of an example where this would break? Comment Actions Hi Andy, I think we are concerned about changing program behavior that somehow might depend/work fine with the wrapping. Signed arithmetic operations in C standard do not wrap while unsigned arithmetic operations wrap. So if you have unsigned char a,b and try to add them: while if you have char a, b when you add them: If we promote an unsigned IV to 64-bit, we believe it has to be done so that it does not change the program behavior. Example: use(i) In this example what are the safe conditions to promote i to a larger size so that we do not change the program behavior? So we decided to use SCEV analysis step info to allow widening the unsigned IV only when we are sure we do not change the program behavior. What do you think? Comment Actions FWIW, my commit that reverted unsigned comparison widening (r217962) was speculative and just so happened to appease the buildbots. I suspect the real issue was addressed in r218539. Comment Actions At the LLVM IR level, there is no assumption about signed or unsigned arithmetic wrapping. Either SCEV must prove a value does not wrap based on loop conditions, or it must be inferred from the add operation's nsw or nuw attributes. By the time WidenLoopCompare has been called, SCEV has proven that the IV recurrence does not wrap in the signed or unsigned sense (depending on IsSigned). Maybe it helps to think about it this way: You could have safely implemented compare widening by first transforming the IR as follows: Loop: Then indvars would come along and widen the IV: Loop: But you're widening the compare after WidenIV has already proven that this zero extend would be unnecessary: So you just need to extend the constant. |