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>