On Wed, 16 Dec 2020, Maciej W. Rozycki wrote:

> > CONST_DOUBLE_ATOF ("0", VOIDmode) seems malformed though, and I'd expect
> > it to assert in REAL_MODE_FORMAT (via the format_helper constructor).
> > I'm not sure the patch is strictly safer than the status quo.
> 
>  I may have missed that, though I did follow the chain of calls involved 
> here to see if there is anything problematic.  As I say I have a limited 
> way to verify this in practice as the PDP-11 code involved appears to me 
> to be dead, and the situation does not apply to the VAX backend.  Maybe I 
> could simulate it somehow artificially to see what happens.

 I have made an experiment and arranged for a couple of builtins to refer
to CONST_DOUBLE_ATOF ("0", VOIDmode) via expanders and it works just fine 
except for failing to match an RTL insn, like:

builtin.c: In function 't':
builtin.c:18:1: error: unrecognizable insn:
   18 | }
      | ^
(insn 6 3 7 2 (set (reg/v:SF 23 [ f ])
        (plus:SF (const_double 0 [0] 0 [0] 0 [0] 0 [0])
            (reg/v:SF 32 [ f ]))) "builtin.c":5:6 -1
     (nil))
during RTL pass: vregs
builtin.c:18:1: internal compiler error: in extract_insn, at recog.c:2315

so it does work in principle and would produce something if there was a 
matching insn.

> > FWIW, I agree with Jeff that this ought to be CONST0_RTX (mode).
> 
>  I'll have to update several places then and push the changes through full 
> regression testing, so it'll probably take until the next week.

 FWIW, CONST_DOUBLE_ATOF ("0", VOIDmode) is of course not equivalent to 
CONST0_RTX (VOIDmode), as the latter produces a CONST_INT rather than a 
CONST_DOUBLE rtx:

builtin.c: In function 't':
builtin.c:18:1: error: unrecognizable insn:
   18 | }
      | ^
(insn 6 3 7 2 (set (reg/v:SF 23 [ f ])
        (plus:SF (const_int 0 [0])
            (reg/v:SF 32 [ f ]))) "builtin1.c":5:6 -1
     (nil))
during RTL pass: vregs
builtin.c:18:1: internal compiler error: in extract_insn, at recog.c:2315

I suppose we do not have to support VOIDmode here, but I feel a bit uneasy 
about the lack of identity mapping between machine description (where in 
principle we could already use `const_double' with any mode, not only ones 
CONST0_RTX expands to a CONST_DOUBLE for) and RTL produced if CONST0_RTX 
was used rather than CONST_DOUBLE_ATOF, as CONST0_RTX does not always 
return a CONST_DOUBLE rtx.

 For the sake of the experiment I modified machine description further so 
as to actually let the rtx produced by CONST_DOUBLE_ATOF ("0", VOIDmode) 
through by providing suitable insns, and here's an excerpt from annotated 
artificial assembly produced:

#(insn 6 21 7 (set (reg/v:SF 0 %r0 [orig:23 f ] [23])
#        (plus:SF (const_double 0 [0] 0 [0] 0 [0] 0 [0])
#            (mem/c:SF (plus:SI (reg/f:SI 12 %ap)
#                    (const_int 4 [0x4])) [1 f+0 S4 A32]))) "builtin.c":5:6 199 
{*addzsf3}
#     (expr_list:REG_DEAD (reg/f:SI 12 %ap)
#        (nil)))
        #addf3 $0,4(%ap),%r0    # 6     [c=40]  *addzsf3

The CONST_DOUBLE rtx yielded the `$0' operand, so the expression made it 
through the backend down to generated assembly (the leading comment 
character comes from the artificial `*addzsf3' insn in modified MD).

 So with the CONST_DOUBLE_ATOF approach we have a coherent generic model 
where we can express arbitrary modes with CONST_DOUBLE rtxes without the 
need to analyse in the parser (genemit.c) whether the expression requested 
makes sense or not.  Whereas with the CONST0_RTX approach we'll either 
have to diagnose odd `const_double_zero' usage (making it inconsistent 
with `const_zero') or leave it to the undefined (and again inconsistent).

 What I think we want to do though is to make CONST_DOUBLE_ATOF ("0", 
mode) effectively alias to CONST0_RTX (mode) in the cases where the rtx 
produced is of the CONST_DOUBLE type.  By the look of `init_emit_once' I 
infer we do that already, so I must conclude that the choice between:

          printf ("CONST_DOUBLE_ATOF (\"0\", %smode)",
                  GET_MODE_NAME (GET_MODE (x)));

and:

          printf ("CONST0_RTX (%smode)",
                  GET_MODE_NAME (GET_MODE (x)));

for genemit.c is for those cases merely syntactic.  So I think I made the 
correct choice here and I'd still rather go with CONST_DOUBLE_ATOF, in 
which case we can simply ignore uninteresting modes.

 Have I expressed myself clearly enough?  I can post the patch I made the 
experiments with and builtin.c for the context.

 NB the festive season and the turn of events beforehand has delayed me a 
bit, but I now have a proper fix for the issue considered here, which 
actually removes the current use of VOIDmode with CONST_DOUBLE, and it's 
now only a matter of CONST0_RTX vs CONST_DOUBLE_ATOF to be used there.  
I'll post the patch shortly and we can continue the discussion in that 
context then.

 Thank you both for your input.

  Maciej

Reply via email to