On Fri, Jan 12, 2024 at 6:30 PM Qing Zhao <qing.z...@oracle.com> wrote: > > Thanks a lot for the reply. > > > On Jan 12, 2024, at 11:28 AM, Richard Biener <richard.guent...@gmail.com> > > wrote: > > > > > > > >> Am 12.01.2024 um 16:55 schrieb Qing Zhao <qing.z...@oracle.com>: > >> > >> Hi, > >> > >> I have some questions on using the utility routine “unshare_expr”: > >> > >> From my understanding, there should be NO shared nodes in a GENERIC > >> function. > >> Otherwise, gimplication might fail. > > > > There is sharing and this is why we unshare everything before > > gimplification. > > Okay, so, the "unsharing everything” is done automatically by the compiler > before gimplification? > I don’t need to worry about this? > > I see many places in FE where “unshare_expr” is used, for example, > “ubsan_instrument_division”, > “ubsan_instrument_shift”, etc.
It's likely doing sth during gimplification. > So, usually, when should “unshare_expr” be used? You should usually unshare when you are putting the same 'tree' into multiple operands. Using a SAVE_EXPR avoids redundant code but it also requires that the SAVE_EXPR uses are ordered. > >> Therefore, when we insert new tree nodes manually into the GENERIC > >> function, we should > >> Make sure there is no shared nodes introduced. > >> > >> 1. Is the above understanding correct? > > > > No > > > >> 2. Is there any tool to check there is no shared nodes in the GENERIC > >> function? > >> 3. Are there any tree nodes that are allowed to be shared in a GENERIC > >> function? If so, what are they? > > > > There’s some allowed sharing on GIMPLE and a verifier. > What’s the name of the verifier that I can search and check? verify_node_sharing > > > >> 4. For the following: > >> > >> If both “op1” and “op2” are existing tree nodes in the current GENERIC > >> function, > >> and we will insert a new tree node: > >> > >> tree new_tree = build2 (CODE, TYPE, op1, op2) > >> > >> > >> Should we add “unshare_expr” on both “op1” and “op2” as: > >> > >> Tree new_tree = build2 (CODE, TYPE, unshare_expr (op1), unshare_expr (op2)) > >> ? > > > > Not necessarily but instead you have to watch for evaluating side-effects > > only once. See save_expr. > > Okay. I see. > > > >> > >> If op2 is a node that is allowed to be shared, whether the additional > >> “unshare_expr” on it trigger any potential problem? > > > > If you unshare side-effects that’s generating wrong-code. Otherwise > > unsharing is safe. > > Okay. > Will unnecessary unshareing produce redundant IRs? Yes. > All my questions for unshare_expr relate to a LTO bug that I currently stuck > with > when using .ACCESS_WITH_SIZE in bound sanitizer (only with -flto, without > -flto, no issue): > > [opc@qinzhao-aarch64-ol8 gcc]$ sh t > during IPA pass: modref > t.c:20:1: internal compiler error: tree code ‘ssa_name’ is not supported in > LTO streams > 0x14c3993 lto_write_tree > ../../latest-gcc-write/gcc/lto-streamer-out.cc:561 > 0x14c3aeb lto_output_tree_1 > > And the value of the tree node that triggered the ICE is: > (gdb) call debug_tree(expr) > <ssa_name 0xfffff5761e60 type <error_mark 0xfffff56c0e58> > nothrow > def_stmt > version:13 in-free-list> > > Is there any good way to debug LTO bug? This happens usually when you have a VLA type and its type fields are not properly gimplified which usually happens because the frontend fails to insert a gimplification point for it (a DECL_EXPR). > Thanks a lot for the help. > > Qing > > > > > > Richard > > > >> Thanks a lot for your help. > >> > >> Qing >