Hi,
This code:
@str = private constant [1 x i8] zeroinitializer
define internal i8* @f(i8* %p) nounwind readnone {
%q = getelementptr inbounds i8* %p, i32 1
ret i8* %q
}
define i32 @main() nounwind {
%p = call i8* @f(i8* getelementptr ([1 x i8]* @str, i32 0, i32 0)) nounwind
%c = icmp eq i8* %p, getelementptr ([1 x i8]* @str, i32 1, i32 0)
br i1 %c, label %pass, label %fail
fail:
tail call void @abort() noreturn nounwind
unreachable
pass:
ret i32 0
}
declare void @abort()
appears to be mis-optimised by "opt -ipsccp" into this:
define internal i8* @f(i8* %p) nounwind readnone {
ret i8* undef
}
define i32 @main() nounwind {
%p = call i8* @f(i8* getelementptr ([1 x i8]* @str, i32 0, i32 0)) nounwind
br label %fail
fail:
tail call void @abort() noreturn nounwind
unreachable
}
>From looking at the debug output, IPSCCP works out that the result of
the call to @f will be:
i8* getelementptr ([1 x i8]* @str, i32 0, i32 1)
which is compared with:
i8* getelementptr ([1 x i8]* @str, i32 1, i32 0)
and it thinks that these two expressions are different, so the
comparison will return false.
I can see that these two getelementptr expressions don't have exactly
the same indexes in the same place, but surely they both evaluate to
the same thing, namely one byte after the start of @str, so they
should be considered equal?
I'm using an LLVM 2.6-based tree - I haven't checked the behaviour
with current svn trunk.
Thanks,
Jay.