[LLVMdev] A potential bug
Eli Friedman
eli.friedman at gmail.com
Thu Oct 6 14:28:15 PDT 2011
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
>
>
More information about the llvm-dev
mailing list