On Thu, Oct 6, 2011 at 2:20 PM, Eli Friedman <eli.friedman at gmail.com> wrote:> On Thu, Oct 6, 2011 at 2:12 PM, Zeng Bin <ezengbin at gmail.com> wrote: >> Hi all, >> >> There might be a bug in DeadStoreElimination.cpp. This pass eliminates >> stores backwards aggressively in an end BB. It does not check dependencies >> on stores in an end BB though. For example, in this code snippet: >> ... >> 1. %sum.safe_r47.pre-phi = phi i64* [ %sum.safe_r47.pre, >> %entry.for.end_crit_edge ], [ %sum.safe_r42, %for.body ] >> 2. %call9 = call i32 @gettimeofday(%struct.timeval* %end, %struct.timeval* >> null) nounwind >> 3. %0 = bitcast %struct.timeval* %start to i64* // eliminated by >> HandleEndBlock in DeadStoreElimination.cpp >> 4. %1 = bitcast %struct.timeval* %agg.tmp to i64* // eliminated ... >> 5. %tmp49 = load i64* %0, align 8 // eliminated >> ... >> 6. store i64 %tmp49, i64* %1, align 8 // eliminated >> ... >> 7. %2 = bitcast %struct.timeval* %end to i64* // eliminated ... >> 8. %3 = bitcast %struct.timeval* %agg.tmp12 to i64* // eliminated ... >> 9. %tmp50 = load i64* %2, align 8 // >> eliminated ... >> 10. store i64 %tmp50, i64* %3, align 8 // >> eliminated ... >> 11. %tv_sec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 0, i32 >> 0 >> 12. %tv_sec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_sec) // >> intrinsic function call inserted by me >> 13. %tmp15 = load i32* %tv_sec.safe_r, align 4, !tbaa >> !4 // this loads the value stored at line 6 >> 14. %tv_usec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 0, i32 >> 1 >> 15. %tv_usec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_usec) // >> intrinsic function call ... >> 16. %tmp16 = load i32* %tv_usec.safe_r, align 4, !tbaa !4 >> 17. %tv_sec17 = getelementptr inbounds %struct.timeval* %agg.tmp12, i32 0, >> i32 0 >> 18. %tv_sec17.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_sec17) // >> intrinsic function call ... >> 19. %tmp18 = load i32* %tv_sec17.safe_r, align 4, !tbaa !4 >> 20. %tv_usec19 = getelementptr inbounds %struct.timeval* %agg.tmp12, i32 0, >> i32 1 >> 21. %tv_usec19.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_usec19) >> // intrinsic function call >> 22. %tmp20 = load i32* %tv_usec19.safe_r, align 4, !tbaa !4 >> 23. %call21 = call i32 @delta(i32 %tmp15, i32 %tmp16, i32 %tmp18, i32 >> %tmp20) >> ... >> >> It is compiled by clang 2.9. This BB is an end block in a function. >> Intrinsic function llvm.guard.load.p0i32 is defined as follows: >> let Properties = [IntrNoMem, NoCapture<0>] in { >> def int_guard_load : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>]> >> } >> >> Thanks a lot. > > IntrNoMem means that your intrinsic doesn't access memory... I don't > think that is what you want.Well, either that or the NoCapture marking is wrong. What exactly is your int_guard_load supposed to do? -Eli
It does not do anything. It is an abstract function which transforms a pointer and returns another pointer of the same type. It does not visit memory or capture the pointer parameter. On Thu, Oct 6, 2011 at 2:22 PM, Eli Friedman <eli.friedman at gmail.com> wrote:> On Thu, Oct 6, 2011 at 2:20 PM, Eli Friedman <eli.friedman at gmail.com> > wrote: > > On Thu, Oct 6, 2011 at 2:12 PM, Zeng Bin <ezengbin at gmail.com> wrote: > >> Hi all, > >> > >> There might be a bug in DeadStoreElimination.cpp. This pass eliminates > >> stores backwards aggressively in an end BB. It does not check > dependencies > >> on stores in an end BB though. For example, in this code snippet: > >> ... > >> 1. %sum.safe_r47.pre-phi = phi i64* [ %sum.safe_r47.pre, > >> %entry.for.end_crit_edge ], [ %sum.safe_r42, %for.body ] > >> 2. %call9 = call i32 @gettimeofday(%struct.timeval* %end, > %struct.timeval* > >> null) nounwind > >> 3. %0 = bitcast %struct.timeval* %start to i64* // eliminated > by > >> HandleEndBlock in DeadStoreElimination.cpp > >> 4. %1 = bitcast %struct.timeval* %agg.tmp to i64* // eliminated ... > >> 5. %tmp49 = load i64* %0, align 8 // > eliminated > >> ... > >> 6. store i64 %tmp49, i64* %1, align 8 // > eliminated > >> ... > >> 7. %2 = bitcast %struct.timeval* %end to i64* // eliminated > ... > >> 8. %3 = bitcast %struct.timeval* %agg.tmp12 to i64* // eliminated ... > >> 9. %tmp50 = load i64* %2, align 8 // > >> eliminated ... > >> 10. store i64 %tmp50, i64* %3, align 8 // > >> eliminated ... > >> 11. %tv_sec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 0, > i32 > >> 0 > >> 12. %tv_sec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_sec) > // > >> intrinsic function call inserted by me > >> 13. %tmp15 = load i32* %tv_sec.safe_r, align 4, !tbaa > >> !4 // this loads the value stored at line 6 > >> 14. %tv_usec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 0, > i32 > >> 1 > >> 15. %tv_usec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_usec) > // > >> intrinsic function call ... > >> 16. %tmp16 = load i32* %tv_usec.safe_r, align 4, !tbaa !4 > >> 17. %tv_sec17 = getelementptr inbounds %struct.timeval* %agg.tmp12, i32 > 0, > >> i32 0 > >> 18. %tv_sec17.safe_r = call i32* @llvm.guard.load.p0i32(i32* > %tv_sec17) // > >> intrinsic function call ... > >> 19. %tmp18 = load i32* %tv_sec17.safe_r, align 4, !tbaa !4 > >> 20. %tv_usec19 = getelementptr inbounds %struct.timeval* %agg.tmp12, > i32 0, > >> i32 1 > >> 21. %tv_usec19.safe_r = call i32* @llvm.guard.load.p0i32(i32* > %tv_usec19) > >> // intrinsic function call > >> 22. %tmp20 = load i32* %tv_usec19.safe_r, align 4, !tbaa !4 > >> 23. %call21 = call i32 @delta(i32 %tmp15, i32 %tmp16, i32 %tmp18, i32 > >> %tmp20) > >> ... > >> > >> It is compiled by clang 2.9. This BB is an end block in a function. > >> Intrinsic function llvm.guard.load.p0i32 is defined as follows: > >> let Properties = [IntrNoMem, NoCapture<0>] in { > >> def int_guard_load : Intrinsic<[llvm_anyptr_ty], > [LLVMMatchType<0>]> > >> } > >> > >> Thanks a lot. > > > > IntrNoMem means that your intrinsic doesn't access memory... I don't > > think that is what you want. > > Well, either that or the NoCapture marking is wrong. What exactly is > your int_guard_load supposed to do? > > -Eli >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20111006/d685d5f6/attachment.html>
If int_guard_load returns a pointer based on the passed-in pointer, it captures it (at least according to the definition of "capture" which NoCapture uses). -Eli On Thu, Oct 6, 2011 at 2:26 PM, Zeng Bin <ezengbin at gmail.com> wrote:> It does not do anything. It is an abstract function which transforms a > pointer and returns another pointer of the same type. It does not visit > memory or capture the pointer parameter. > > On Thu, Oct 6, 2011 at 2:22 PM, Eli Friedman <eli.friedman at gmail.com> wrote: >> >> On Thu, Oct 6, 2011 at 2:20 PM, Eli Friedman <eli.friedman at gmail.com> >> wrote: >> > On Thu, Oct 6, 2011 at 2:12 PM, Zeng Bin <ezengbin at gmail.com> wrote: >> >> Hi all, >> >> >> >> There might be a bug in DeadStoreElimination.cpp. This pass eliminates >> >> stores backwards aggressively in an end BB. It does not check >> >> dependencies >> >> on stores in an end BB though. For example, in this code snippet: >> >> ... >> >> 1. %sum.safe_r47.pre-phi = phi i64* [ %sum.safe_r47.pre, >> >> %entry.for.end_crit_edge ], [ %sum.safe_r42, %for.body ] >> >> 2. %call9 = call i32 @gettimeofday(%struct.timeval* %end, >> >> %struct.timeval* >> >> null) nounwind >> >> 3. %0 = bitcast %struct.timeval* %start to i64* // >> >> eliminated by >> >> HandleEndBlock in DeadStoreElimination.cpp >> >> 4. %1 = bitcast %struct.timeval* %agg.tmp to i64* // eliminated >> >> ... >> >> 5. %tmp49 = load i64* %0, align 8 // >> >> eliminated >> >> ... >> >> 6. store i64 %tmp49, i64* %1, align 8 // >> >> eliminated >> >> ... >> >> 7. %2 = bitcast %struct.timeval* %end to i64* // >> >> eliminated ... >> >> 8. %3 = bitcast %struct.timeval* %agg.tmp12 to i64* // eliminated >> >> ... >> >> 9. %tmp50 = load i64* %2, align 8 // >> >> eliminated ... >> >> 10. store i64 %tmp50, i64* %3, align 8 // >> >> eliminated ... >> >> 11. %tv_sec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 0, >> >> i32 >> >> 0 >> >> 12. %tv_sec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_sec) >> >> // >> >> intrinsic function call inserted by me >> >> 13. %tmp15 = load i32* %tv_sec.safe_r, align 4, !tbaa >> >> !4 // this loads the value stored at line 6 >> >> 14. %tv_usec = getelementptr inbounds %struct.timeval* %agg.tmp, i32 >> >> 0, i32 >> >> 1 >> >> 15. %tv_usec.safe_r = call i32* @llvm.guard.load.p0i32(i32* %tv_usec) >> >> // >> >> intrinsic function call ... >> >> 16. %tmp16 = load i32* %tv_usec.safe_r, align 4, !tbaa !4 >> >> 17. %tv_sec17 = getelementptr inbounds %struct.timeval* %agg.tmp12, >> >> i32 0, >> >> i32 0 >> >> 18. %tv_sec17.safe_r = call i32* @llvm.guard.load.p0i32(i32* >> >> %tv_sec17) // >> >> intrinsic function call ... >> >> 19. %tmp18 = load i32* %tv_sec17.safe_r, align 4, !tbaa !4 >> >> 20. %tv_usec19 = getelementptr inbounds %struct.timeval* %agg.tmp12, >> >> i32 0, >> >> i32 1 >> >> 21. %tv_usec19.safe_r = call i32* @llvm.guard.load.p0i32(i32* >> >> %tv_usec19) >> >> // intrinsic function call >> >> 22. %tmp20 = load i32* %tv_usec19.safe_r, align 4, !tbaa !4 >> >> 23. %call21 = call i32 @delta(i32 %tmp15, i32 %tmp16, i32 %tmp18, i32 >> >> %tmp20) >> >> ... >> >> >> >> It is compiled by clang 2.9. This BB is an end block in a function. >> >> Intrinsic function llvm.guard.load.p0i32 is defined as follows: >> >> let Properties = [IntrNoMem, NoCapture<0>] in { >> >> def int_guard_load : Intrinsic<[llvm_anyptr_ty], >> >> [LLVMMatchType<0>]> >> >> } >> >> >> >> Thanks a lot. >> > >> > IntrNoMem means that your intrinsic doesn't access memory... I don't >> > think that is what you want. >> >> Well, either that or the NoCapture marking is wrong. What exactly is >> your int_guard_load supposed to do? >> >> -Eli > >