[llvm-dev] Missed opportunity in the midend, unsigned comparison

David Zarzycki via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 1 07:18:33 PST 2018


For whatever it may be worth, __builtin_assume() helps generate the right code, so it seems like this optimization is within reach:

char arr[2];
char *get(unsigned ind) {
  if (ind >= 1) {
    return 0;
  }
  __builtin_assume(ind < 1);
  return &(arr[ind]);
}


> On Feb 28, 2018, at 18:33, Alexey Zhikhartsev via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> 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
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180301/68efb9ae/attachment-0001.html>


More information about the llvm-dev mailing list