[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