On 12/5/23 07:53, Richard Biener via Gcc wrote:
On Tue, Dec 5, 2023 at 3:54 PM Alexander Monakov via Gcc
<gcc@gcc.gnu.org> wrote:

Greetings,

the definitions for NOP_EXPR and CONVERT_EXPR in tree.def, having survived
all the way from 1992, currently say:

     /* Represents a conversion of type of a value.
        All conversions, including implicit ones, must be
        represented by CONVERT_EXPR or NOP_EXPR nodes.  */
     DEFTREECODE (CONVERT_EXPR, "convert_expr", tcc_unary, 1)

     /* Represents a conversion expected to require no code to be generated.  */
     DEFTREECODE (NOP_EXPR, "nop_expr", tcc_unary, 1)

Unfortunately, they are confusing, as in

     float f(double d)
     {
         return d;
     }

the narrowing conversion is represented with NOP_EXPR, and it is definitely
not a no-op.

Does some clear distinction remain, and is it possible to clarify the
definitions?

{NOP,CONVERT}_EXPR are interchangeable in the middle-end but
frontends (IIRC the C++ FE mainly) distinguishes them.  So a uniform
documentation might be difficult - in the end we could eventually
drop NOP_EXPR from the middle-end (during gimplification?) and
only use CONVERT_EXPR.  All uses should use CASE_CONVERT
or CONVERT_EXPR_CODE_P which globs both.
I thought someone looked at this a while ago (measured in years) and concluded it wasn't actually feasible. Perhaps because the middle end still hands things off to routines that are also used by the FE.

I could see dropping/converting during gimplification with a checker that verifies they don't sneak back in. Then we can start to expunge them from gimple passes. Feels like a gcc-15+ problem to me.

jeff

Reply via email to