-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
| Bugzilla Link | 8883 |
| Resolution | FIXED |
| Resolved on | Jan 06, 2011 00:20 |
| Version | 1.0 |
| OS | All |
| CC | @sunfishcode |
Extended Description
This code:
void fill(Iterator first, Iterator last, T value) {
while (first != last) *first++ = value;
}
char X[1000];
void foo() {
fill(X, X+1000, 0);
}
Compiles with: clang t.cpp -S -o - -emit-llvm -O3
into:
...
while.body.i: ; preds = %while.body.i, %entry
%indvar.i = phi i64 [ 0, %entry ], [ %indvar.next.i, %while.body.i ]
%first.addr.05.i = getelementptr [1000 x i8]* @X, i64 0, i64 %indvar.i
store i8 0, i8* %first.addr.05.i, align 1, !tbaa !0
%indvar.next.i = add i64 %indvar.i, 1
%exitcond = icmp eq i64 %indvar.next.i, ptrtoint (i8* getelementptr ([1000 x i8]* @X, i64 1, i64 sub (i64 0, i64 ptrtoint ([1000 x i8]* @X to i64))) to i64)
br i1 %exitcond, label %Z4fillIPciEvT_S1_T0.exit, label %while.body.i
Notice the poor icmp, which should be comparing the indvar against 1000. SCEV should simplify this away. This can also be seen in simple_types_constant_folding.llvm.bc in Nehalem:SingleSource/Benchmarks/Adobe-C++ where SCEV is expanding an expression for the loop-idiom pass, resulting in this crazy memset:
call void @llvm.memset.p0i8.i64(i8* getelementptr inbounds ([8000 x i8]* @data8, i64 0, i64 0), i8 %11, i64 ptrtoint (i8* getelementptr ([8000 x i8]* @data8, i64 1, i64 sub (i64 0, i64 ptrtoint ([8000 x i8]* @data8 to i64))) to i64), i32 16, i1 false)
Codegen is able to simplify the constant to "8000", but the expression simplification logic in SCEV should do this. This may be just a matter of using lib/Analysis/ConstantFolding APIs with target data in scev.