[PATCH] [IndVarSimplify] Widen signed loop compare instructions to enable additional optimizations.
Nick White
n.j.white at gmail.com
Thu Sep 25 01:47:15 PDT 2014
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
More information about the llvm-commits
mailing list