Hi everybody, I see a missed optimization opportunity in LLVM that GCC catches and I’d love to hear community’s input.
Here’s the original C code:
1 char arr[2];
2 char *get(unsigned ind) {
3 if (ind >= 1) {
4 return 0;
5 }
6 return &(arr[ind]);
7 }
The variable ind
is unsigned so, based on the comparison, if it is not greater or equals to one, than it is must be equal to zero. GCC understands that ind
equals to zero at line 6 and generates something like the following (in pseudocode, the x86 assembly is in the footnotes):
ret = 0
if ind == 0:
ret = arr
return ret
On the other hand, the development version of LLVM produces the following IR:
; Function Attrs: nounwind
define i8* @get(i32 %ind) local_unnamed_addr #0 {
entry:
%cmp = icmp eq i32 %ind, 0
%arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* @arr, i32 0, i32 %ind
%retval.0 = select i1 %cmp, i8* %arrayidx, i8* null
ret i8* %retval.0
}
The variable arrayidx
is always calculated even though we could simply return arr
when ind
equals to zero.
Is this kind of optimization already implemented somewhere in LLVM? If not, what is the best place to implement it at? Thank you very much in advance.
Best,
Alex