http://llvm.org/bugs/show_bug.cgi?id=5822
Summary: StringRef::endswith compiles into gross code
Product: libraries
Version: 1.0
Platform: PC
OS/Version: All
Status: NEW
Keywords: code-quality
Severity: normal
Priority: P2
Component: Support Libraries
AssignedTo: [email protected]
ReportedBy: [email protected]
CC: [email protected], [email protected]
This code:
#include "llvm/ADT/StringRef.h"
bool test(llvm::StringRef R) { return R.endswith("x"); }
bool test2(llvm::StringRef R) { return !R.empty() && R.back() == 'x'; }
compiles into:
define zeroext i8 @_Z4testN4llvm9StringRefE(i8* %R.0, i64 %R.1) nounwind
readonly ssp {
entry:
%0 = add i64 %R.1, -1 ; <i64> [#uses=2]
%1 = icmp ult i64 %0, %R.1 ; <i1> [#uses=1]
%iftmp.50.0.i.i.i = select i1 %1, i64 %0, i64 %R.1 ; <i64> [#uses=4]
%2 = icmp ugt i64 %iftmp.50.0.i.i.i, %R.1 ; <i1> [#uses=1]
%iftmp.51.0.i.i.i = select i1 %2, i64 %iftmp.50.0.i.i.i, i64 %R.1 ; <i64>
[#uses=2]
%3 = icmp ult i64 %iftmp.51.0.i.i.i, %R.1 ; <i1> [#uses=1]
%iftmp.50.0.i5.i.i = select i1 %3, i64 %iftmp.51.0.i.i.i, i64 %R.1 ; <i64>
[#uses=1]
%4 = sub i64 %iftmp.50.0.i5.i.i, %iftmp.50.0.i.i.i ; <i64> [#uses=1]
%5 = icmp eq i64 %4, 1 ; <i1> [#uses=1]
br i1 %5, label %bb.i.i, label %_ZNK4llvm9StringRef8endswithES0_.exit
bb.i.i: ; preds = %entry
%6 = getelementptr inbounds i8* %R.0, i64 %iftmp.50.0.i.i.i ; <i8*> [#uses=1]
%lhsv = load i8* %6 ; <i8> [#uses=1]
%7 = icmp eq i8 %lhsv, 120 ; <i1> [#uses=1]
%retval.i.i = zext i1 %7 to i8 ; <i8> [#uses=1]
ret i8 %retval.i.i
_ZNK4llvm9StringRef8endswithES0_.exit: ; preds = %entry
ret i8 0
}
which is pretty gross. This is due to instcombine not zapping the max's, which
may be due to StringRef being written wrong (e.g. using unsigned instead of
signed integers). GCC also generates nasty code.
This should compile down into:
return !R.empty() && R.back() == 'x';
which codegen's to:
define zeroext i8 @_Z5test2N4llvm9StringRefE(i8* %R.0, i64 %R.1) ssp {
entry:
%0 = icmp eq i64 %R.1, 0 ; <i1> [#uses=1]
br i1 %0, label %bb8, label %_ZNK4llvm9StringRef4backEv.exit
_ZNK4llvm9StringRef4backEv.exit: ; preds = %entry
%1 = add i64 %R.1, -1 ; <i64> [#uses=1]
%2 = getelementptr inbounds i8* %R.0, i64 %1 ; <i8*> [#uses=1]
%3 = load i8* %2, align 1 ; <i8> [#uses=1]
%4 = icmp eq i8 %3, 120 ; <i1> [#uses=1]
%retval = zext i1 %4 to i8 ; <i8> [#uses=1]
ret i8 %retval
bb8: ; preds = %entry
ret i8 0
}
In .s, this is the difference:
__Z4testN4llvm9StringRefE:
Leh_func_begin1:
leaq -1(%rsi), %rax
movq %rsi, %rcx
cmpq %rsi, %rax
cmovae %rsi, %rax
cmpq %rsi, %rax
cmova %rax, %rcx
cmpq %rsi, %rcx
cmovae %rsi, %rcx
subq %rax, %rcx
cmpq $1, %rcx
jne LBB1_2
cmpb $120, (%rdi,%rax)
sete %al
movzbl %al, %eax
ret
LBB1_2:
xorl %eax, %eax
ret
vs
__Z5test2N4llvm9StringRefE:
Leh_func_begin2:
testq %rsi, %rsi
je LBB2_2
cmpb $120, -1(%rsi,%rdi)
sete %al
movzbl %al, %eax
ret
LBB2_2:
xorl %eax, %eax
ret
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
_______________________________________________
LLVMbugs mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs