raghesh via llvm-dev
2019-Sep-24 08:25 UTC
[llvm-dev] An issue with "lifetime.start" and storing "undef"
Hi All, In order to confine the scope of a local variable allocated using "alloca", we had written a pass named 'undeflocal'. This helps avoid pseudo phi nodes inserted because of the path (carrying an undefined value) starting from the "entry" block. This unwanted phi instruction was preventing some of the optimizations from getting triggered later on. For example, consider the following case: // void fn() { // Block 1.... block 3 // for (i=0 ; i<n ; i++) { // int k; // if (<>) // define k // use of k // } Though the value of k gets defined in the "if" block inside the "for" loop, due to the presence of "alloca" in entry block, the initial garbage value of k flows from the entry block of the function. This expands the scope of the variable k. The undeflocal pass adds a store instruction (say SI) to store value "undef", to the local variable pointer. SI is added just "before" the "lifetime.start" intrinsic for the variable k; the intention was to kill the liveness of the variable k at this point and help avoid insertion of the phi instruction. However, now we are facing an issue triggered by the AddressSanitizer, when "clang" is built using our bootstrap build. It throws the "stack-use-after-scope" error. We identified this is due to the "store" introduced by "undeflocal" pass before the lifetime.start intrinsic. The value of the additional store is changed to “0” in place of “undef” by the SROA pass later invoked. As “undeflocal” has inserted it before the lifetime.start intrinsic and now the store has a legal value “0” stored into it, which in turn causes the address sanitizer to complain about use-after-scope. Here is the part of the IR that does this *After undeflocal* if.end9: ; preds %_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit, %if.then8 %Cascade.0 = phi i32 [ %7, %_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit ], [ %8, %if.then8 ], !dbg !22012 store i64 undef, i64* %Cost, align 8, !dbg !22013 %9 = bitcast i64* %Cost to i8*, !dbg !22013 call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %9) #24, !dbg !22013 *After SROA* if.end9: ; preds %_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit, %if.then8 %Cascade.0 = phi i32 [ %7, %_ZN4llvm10IndexedMapIN12_GLOBAL__N_18RAGreedy7RegInfoENS_20VirtReg2IndexFunctorEEixEj.exit ], [ %8, %if.then8 ], !dbg !22012 store i32 0, i32* %Cost.sroa.10, !dbg !22013 %Cost.sroa.10.0..sroa_cast349 = bitcast i32* %Cost.sroa.10 to i8*, !dbg !22013 call void @llvm.lifetime.start.p0i8(i64 4, i8* %Cost.sroa.10.0..sroa_cast349), !dbg !22013 It could be great, if we get suggestions for the proper solution for this. We have thought about the following solutions, however, not certain about its implications on other passes. 1. To make “undeflocal” pass add the store instruction after lifetime.start. 2. To stop SROA from converting undef to 0. 3. To add 'metadata', to SI so that the AddressSanitizer ignores SI. We are skeptical about the solution 1 because the semantics of lifetime.start defined in "lib/CodeGen/StackColoring.cpp" is a bit confusing. It says: // L2) on a `lifetime.start`, a stack slot is marked as *in-scope* and // the stack slot is overwritten with `undef`. As it mentioned, "on" a 'lifteime.start', we are unsure about if it is meant to be before or after it. Will there be any issue in later passes, if we have an "undef" value "store" after lifetime.start. Regards, ------------------------------ Raghesh Aloor AMD India Pvt. Ltd. Bengaluru. ------------------------------ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190924/afdf1db4/attachment.html>
Tim Northover via llvm-dev
2019-Sep-24 08:56 UTC
[llvm-dev] An issue with "lifetime.start" and storing "undef"
Hi Raghesh, On Tue, 24 Sep 2019 at 09:26, raghesh via llvm-dev <llvm-dev at lists.llvm.org> wrote:> In order to confine the scope of a local variable allocated using "alloca", we had written a pass named 'undeflocal'. This helps avoid pseudo phi nodes inserted because of the path (carrying an undefined value) starting from the "entry" block. This unwanted phi instruction was preventing some of the optimizations from getting triggered later on.It sounds like this is the real problem. Whatever's seeing that store you're inserting and using it to improve the phi should also be taught about @llvm.lifetime.start. Cheers. Tim.
raghesh via llvm-dev
2019-Sep-24 09:22 UTC
[llvm-dev] An issue with "lifetime.start" and storing "undef"
Hi Tim, Are you suggesting solution 3? i.e,. To add 'metadata', to SI so that the AddressSanitizer ignores SI. Regards, ------------------------------ Raghesh Aloor AMD India Pvt. Ltd. Bengaluru. ------------------------------ On Tue, Sep 24, 2019 at 2:27 PM Tim Northover <t.p.northover at gmail.com> wrote:> Hi Raghesh, > > On Tue, 24 Sep 2019 at 09:26, raghesh via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > In order to confine the scope of a local variable allocated using > "alloca", we had written a pass named 'undeflocal'. This helps avoid pseudo > phi nodes inserted because of the path (carrying an undefined value) > starting from the "entry" block. This unwanted phi instruction was > preventing some of the optimizations from getting triggered later on. > > It sounds like this is the real problem. Whatever's seeing that store > you're inserting and using it to improve the phi should also be taught > about @llvm.lifetime.start. > > Cheers. > > Tim. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190924/a260119d/attachment.html>
Maybe Matching Threads
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??
- Any significance for m_OneUse in (X / Y) / Z => X / (Y * Z) ??
- GlobalAddress lowering strategy
- LLVM behavior different depending on function symbol name