Vineet Gupta <vine...@rivosinc.com> writes: > On 6/3/25 08:24, Richard Sandiford wrote: >> I think the issue is that: >> >> (insn 9 8 27 2 (parallel [ >> (asm_operands/v ("fsrm %0") ("") 0 [ >> (reg:SI 15 a5 [139]) >> ] >> [ >> (asm_input:SI ("r") frm-run-1.c:33) >> ] >> [] frm-run-1.c:33) >> (clobber (reg:V4096QI 69 frm)) >> ]) "frm-run-1.c":33:3 -1 >> (nil)) >> >> is seen as invalidating FRM and so: >> >> (insn 27 9 28 2 (set (reg:SI 15 a5 [144]) >> (reg:SI 69 frm)) "frm-run-1.c":43:1 2829 {frrmsi} >> (nil)) >> >> is seen as an uninitialised read. I suppose clobbers in inline asms >> need to be treated as real definitions rather than just kills. > > In general or specifically inside of late_combine ?
We can start with the routines that rtl-ssa uses for its dataflow analysis. Does the patch below help? Jeff, Eric: any thoughts about this? Richard >From 29329926acfb15843f6dc3ac83a74a4e055bb3e6 Mon Sep 17 00:00:00 2001 From: Richard Sandiford <richard.sandif...@arm.com> Date: Tue, 3 Jun 2025 17:48:12 +0100 Subject: [PATCH] rtlanal: Treat some asm clobbers as rmw accesses, not kills To: gcc-patches@gcc.gnu.org This patch treats certain asm clobbers as read-modify-write indicators, rather than as mere kills. See the comments in the patch for details. gcc/ * rtlanal.cc asm_clobber_is_read_modify_write_p): New function. (rtx_properties::try_to_add_pattern): Use it when processing CLOBBERs. --- gcc/rtlanal.cc | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 239d6691c4c..b8b563109c1 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -2072,6 +2072,37 @@ note_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data) } } +/* Return true if a clobber of X in an asm statement should be treated for + dataflow purposes as both a read of X and a write of a meaningful value + to X, rather than as a mere kill of X. */ + +static bool +asm_clobber_is_read_modify_write_p (rtx x) +{ + if (MEM_P (x)) + /* Asms that clobber memory can read from and write to arbitrary + memory locations. */ + return true; + + if (REG_P (x) && HARD_REGISTER_P (x)) + /* Some registers are suitable for asm operands. If an asm reads + such a register, it should note that in the input operands. + If it writes a meaningful value to such a register, it should + note that in the output operands. For these registers, a clobber + is just a kill. For example, clobbers of argument registers should + not keep arbitrary earlier code live. + + However, some fixed registers are not suitable for asm operands. + Neither the asm syntax nor the internal representation of asms provide + a direct way of indicating that an asm reads from or writes to such + registers. The only indication that an asm can give is to clobber + the registers. */ + return !range_in_hard_reg_set_p (operand_reg_set, REGNO (x), + REG_NREGS (x)); + + return false; +} + /* Try to add a description of REG X to this object, stopping once the REF_END limit has been reached. FLAGS is a bitmask of rtx_obj_reference flags that describe the context. */ @@ -2262,8 +2293,17 @@ rtx_properties::try_to_add_pattern (const_rtx pat) break; case CLOBBER: - try_to_add_dest (XEXP (pat, 0), rtx_obj_flags::IS_CLOBBER); - break; + { + rtx x = XEXP (pat, 0); + if (has_asm && asm_clobber_is_read_modify_write_p (x)) + { + try_to_add_dest (x); + try_to_add_src (x); + } + else + try_to_add_dest (x, rtx_obj_flags::IS_CLOBBER); + break; + } case SET: try_to_add_dest (SET_DEST (pat)); -- 2.43.0