[llvm-dev] Missed opportunity in the midend, unsigned comparison
Alexey Zhikhartsev via llvm-dev
llvm-dev at lists.llvm.org
Wed Feb 28 15:33:54 PST 2018
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
--------------------------
GCC x86 ASM:
testl %edi, %edi
movl $0, %edx
movl $arr, %eax
cmovne %rdx, %rax
ret
LLVM x86 ASM:
xorl %eax, %eax
testl %edi, %edi
movl %edi, %ecx
leaq arr(%rcx), %rcx
cmoveq %rcx, %rax
retq
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180228/0dbb1182/attachment.html>
More information about the llvm-dev
mailing list