From 20ab43b5cad6ac69a70b01489be0adf98bd421ba Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 5 Dec 2020 18:26:26 +0000 Subject: [PATCH] RTL: Add `const_double_zero' syntactic rtx The use of a constant double zero is required for post-reload compare elimination to be able to discard redundant floating-point comparisons, for example with a VAX RTL instruction stream like: (insn 34 4 3 2 (parallel [ (set (reg/v:DF 0 %r0 [orig:24 x ] [24]) (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32])) (clobber (reg:CC 16 %psl)) ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 37 {*movdf} (nil)) (note 3 34 35 2 NOTE_INSN_FUNCTION_BEG) (insn 35 3 36 2 (set (reg:CCZ 16 %psl) (compare:CCZ (reg/v:DF 0 %r0 [orig:24 x ] [24]) (const_double:DF 0.0 [0x0.0p+0]))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 21 {*cmpdf_ccz} (nil)) (jump_insn 36 35 9 2 (set (pc) (if_then_else (eq (reg:CCZ 16 %psl) (const_int 0 [0])) (label_ref 11) (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz} (int_list:REG_BR_PROB 536870916 (nil)) -> 11) that we want to transform into: (insn 34 4 3 2 (parallel [ (set (reg:CCZ 16 %psl) (compare:CCZ (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32]) (const_double:DF 0.0 [0x0.0p+0]))) (set (reg/v:DF 0 %r0 [orig:24 x ] [24]) (mem/c:DF (plus:SI (reg/f:SI 12 %ap) (const_int 4 [0x4])) [1 x+0 S8 A32])) ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 40 {*movdf_ccz} (nil)) (note 3 34 36 2 NOTE_INSN_FUNCTION_BEG) (jump_insn 36 3 9 2 (set (pc) (if_then_else (eq (reg:CCZ 16 %psl) (const_int 0 [0])) (label_ref 11) (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz} (int_list:REG_BR_PROB 536870916 (nil)) -> 11) with the upcoming MODE_CC representation. For this we need to express the `const_double:DF 0.0 [0x0.0p+0]' rtx as recorded above in the relevant pattern(s) in machine description. The way we represent double constants, as a host-dependent number of wide integers, however means that we currently have no portable way to encode a double zero constant in machine description. Define a syntactic rtx alias then to represent `(const_double 0 0 ...)' as if the suitable number of zeros have been supplied according to the host-specific definition of CONST_DOUBLE_FORMAT. gcc/ * read-rtl.c (rtx_reader::read_rtx_code): Handle syntactic `const_double_zero' rtx. * doc/rtl.texi (Constant Expression Types): Document it. --- gcc/doc/rtl.texi | 18 ++++++++++++++++++ gcc/read-rtl.c | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 4f9b99047ad..7c12991e54d 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -1711,6 +1711,24 @@ machine's or host machine's floating point format. To convert them to the precise bit pattern used by the target machine, use the macro @code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}). +@findex const_double_zero +The host dependency for the number of integers used to store a double +value makes it problematic for machine descriptions to use expressions +of code @code{const_double} and therefore a syntactic alias has been +provided: + +@smallexample +(const_double_zero) +@end smallexample + +standing for: + +@smallexample +(const_double 0 0 @dots{}) +@end smallexample + +for matching the floating-point value zero, possibly the only useful one. + @findex CONST_WIDE_INT @item (const_wide_int:@var{m} @var{nunits} @var{elt0} @dots{}) This contains an array of @code{HOST_WIDE_INT}s that is large enough diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 403f254f3cb..2922af5d111 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -1651,6 +1651,16 @@ rtx_reader::read_rtx_code (const char *code_name) return return_rtx; } + /* Handle "const_double_zero". */ + if (strcmp (code_name, "const_double_zero") == 0) + { + code = CONST_DOUBLE; + return_rtx = rtx_alloc (code); + memset (return_rtx, 0, RTX_CODE_SIZE (code)); + PUT_CODE (return_rtx, code); + return return_rtx; + } + /* If we end up with an insn expression then we free this space below. */ return_rtx = rtx_alloc_for_name (code_name); code = GET_CODE (return_rtx); -- 2.30.2