Alexey Zhikhartsev via llvm-dev
2018-Feb-28 23:33 UTC
[llvm-dev] Missed opportunity in the midend, unsigned comparison
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>
David Zarzycki via llvm-dev
2018-Mar-01 15:18 UTC
[llvm-dev] Missed opportunity in the midend, unsigned comparison
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>