[LLVMdev] A potential bug

Eli Friedman eli.friedman at gmail.com
Thu Oct 6 14:20:22 PDT 2011


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.

-Eli




More information about the llvm-dev mailing list