[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