[llvm-commits] [PATCH] optimise constant arguments in LowerIntrinsicCall()
Jay Foad
jay.foad at gmail.com
Thu May 7 06:28:56 PDT 2009
Given this source:
void f(int *p) {
p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 0;
}
if I compile with optimisation and then run it through the C backend:
$ .../llvm-gcc4.2-2.5-x86-linux-RHEL4/bin/llvm-gcc -emit-llvm -O2 -c m.c
$ llc -march=c -o - m.o
I get:
void f(unsigned int *llvm_cbe_p) {
unsigned char *ltmp_0_1;
*llvm_cbe_p = 0u;
ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int
)1u)])))), (((unsigned int )(unsigned char )((unsigned char )0))),
(((unsigned int )36ull)));
return;
}
The second and third arguments in the call to memset() involve
unnecessary casts of a constant value. This happens because
LowerIntrinsicCall() turns:
call void @llvm.memset.i64(i8* %1, i8 0, i64 36, i32 4)
into:
%2 = trunc i64 36 to i32 ; <i32> [#uses=1]
%3 = zext i8 0 to i32 ; <i32> [#uses=1]
%4 = call i8* @memset(i8* %1, i32 %3, i32 %2) ; <i8*>
and nothing later constant-folds the trunc and zext instructions.
The attached patch addresses this, by optimising LowerIntrinsicCall()
for the case of constant arguments. With this patch applied, the C
backend produces:
ltmp_0_1 = memset((((unsigned char *)((&llvm_cbe_p[((signed int
)1u)])))), 0u, 36u);
The patch passes "make check".
Alternatively, maybe some other optimisation pass could be scheduled
that constant-folds the trunc and zext instructions, but this seems
like overkill to me.
Incidentally, it seems a bit odd that llvm-gcc generates
llvm.memset.i64 instead of llvm.memset.i32 in the first place, but I
haven't investigated why this happens.
Thanks,
Jay.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.lic
Type: application/octet-stream
Size: 5019 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20090507/91c1f37b/attachment.obj>
More information about the llvm-commits
mailing list