[PATCH] [IndVarSimplify] Widen signed loop compare instructions to enable additional optimizations.

Chad Rosier mcrosier at codeaurora.org
Thu Sep 25 07:37:34 PDT 2014


Nick,
The promotion of unsigned comparisons was reverted for this very reason. 
I believe the step has to be a unit step of one to be correct.  There may
be other cases, but this is the only one I can think of at the moment.

Regardless, that part of the code has been reverted.

 Chad

> I'm following up on my mail to [[
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-September/077128.html |
> llvmdev ]] - I don't think this change is quite correct. The test case
> below is a slight modification of the one in the final version of this
> change; it's basically (in C):
>
> ```
> uint32_t test5(uint32_t* a, uint8_t b) {
>   uint32_t sum = 0;
>   for(uint8_t i = 0; i <= b; i += 10) {
>     sum += a[i];
>   }
>   return sum;
> }
> ```
> LLVM IR:
> ```
> ; CHECK-LABEL: @test5
> ; CHECK: zext i8 %b
> ; CHECK: for.cond:
> ; CHECK: phi i64
> ; CHECK: icmp ule i64
>
> define i32 @test5(i32* %a, i8 %b) {
> entry:
>   br label %for.cond
>
> for.cond:
>   %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
>   %i.0 = phi i8 [ 0, %entry ], [ %inc, %for.body ]
>   %cmp = icmp ule i8 %i.0, %b
>   br i1 %cmp, label %for.body, label %for.end
>
> for.body:
>   %idxprom = sext i8 %i.0 to i64
>   %arrayidx = getelementptr inbounds i32* %a, i64 %idxprom
>   %0 = load i32* %arrayidx, align 4
>   %add = add nsw i32 %sum.0, %0
>   %inc = add nsw i8 %i.0, 10
>   br label %for.cond
>
> for.end:
>   ret i32 %sum.0
> }
> ```
>
> If `b` was (e.g.) 251 the loop would be infinite (as it's `for(uint8_t i =
> 0; i < 251; i += 10)`, but when `i` gets to 250 + 10 then `i` wraps and `i
> < 251` is true). If you promote `i` to a `uint64_t` then the loop
> terminates at this point as `260 > 251`. Is this analysis correct?
>
> Thanks -
>
> Nick
>
> http://reviews.llvm.org/D5333
>
>
>

http://reviews.llvm.org/D5333






More information about the llvm-commits mailing list