Hi, Jeff. insert_insn_end_basic_block is to handle this following case: bb 1: ... CALL.---->BB_END of bb bb 2: vfadd rne You can see there is no instructions after CALL. So you we use insert_insn_end_basic_block insert a "frrm" at the end of the bb 1. I know typically it's better to insert a edge between bb 1 and bb 2, then put "frrm" in that edgen. However, it causes ICE. If we really need to follow this approach, it seems that we need to modify the "mode_sw" PASS? Currently, we are avoiding changing the codes of PASS. Thanks. juzhe.zhong@rivai.ai From: Jeff Law Date: 2023-07-27 05:40 To: Robin Dapp; Kito Cheng; Li, Pan2 CC: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; Wang, Yanzhang Subject: Re: [PATCH v7] RISC-V: Support CALL for RVV floating-point dynamic rounding On 7/26/23 07:08, Robin Dapp via Gcc-patches wrote: > So after thinking about it again - I'm still not really sure > I like treating every function as essentially an fesetround. > There is a reason why fesetround is special. Does LLVM behave > the same way? > > But supposing we really, really want it and assuming there's consensus: > > + start_sequence (); > + emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun))); > + rtx_insn *backup_insn = get_insns (); > + end_sequence (); > > A comment here would be nice why we need a sequence for a single > instruction. I'm not fully aware what insert_insn_end_basic_block > does but won't a > > rtx_insn *last = BB_END (bb); > emit_insn_before_noloc (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)), last, bb); > > suffice? One way or another need these kinds of non-local > constructs here don't seem entirely rock solid. Typically an LCM algorithm needs to insert on edges rather than at the end of blocks -- this is particularly important to preserve its property that on no path through the CFG can we have more evaluations of the expression after PRE/LCM than before PRE/LCM. The other thing edge insertions do is simplify the abnormal critical edge problems. I'd have to dig into the precise details, but in the generic PRE/LCM code we clobber the available expressions on critical edges so that we don't try to hold a value live across that edge. Thus the insertion point will tend to be the normal edge of a block that ends with a call to a potentially throwing function. Inserting on the edge also significantly simplifies handling of conditional branches ;-) Jeff