[LLVMbugs] [Bug 5822] New: StringRef::endswith compiles into gross code
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Thu Dec 17 14:38:16 PST 2009
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: unassignedbugs at nondot.org
ReportedBy: clattner at apple.com
CC: llvmbugs at cs.uiuc.edu, daniel at zuster.org
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.
More information about the llvm-bugs
mailing list