diff options
author | Jakub Jelinek <jakub@redhat.com> | 2023-08-29 10:46:01 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2023-08-29 10:46:01 +0200 |
commit | a7aec76a74dd38524be325343158d3049b6ab3ac (patch) | |
tree | a7883f52b7eb101b3e495ead2cc0df15490992d5 /MAINTAINERS | |
parent | 7c04da768c1fc22e0607e3ccad87e2c793499797 (diff) | |
download | gcc-a7aec76a74dd38524be325343158d3049b6ab3ac.zip gcc-a7aec76a74dd38524be325343158d3049b6ab3ac.tar.gz gcc-a7aec76a74dd38524be325343158d3049b6ab3ac.tar.bz2 |
tree-ssa-math-opts: Improve uaddc/usubc pattern matching [PR111209]
The uaddc/usubc usual matching is of the .{ADD,SUB}_OVERFLOW pair in the
middle, which adds/subtracts carry-in (from lower limbs) and computes
carry-out (to higher limbs). Before optimizations (unless user writes
it intentionally that way already), all the steps look the same, but
optimizations simplify the handling of the least significant limb
(one which adds/subtracts 0 carry-in) to just a single
.{ADD,SUB}_OVERFLOW and the handling of the most significant limb
if the computed carry-out is ignored to normal addition/subtraction
of multiple operands.
Now, match_uaddc_usubc has code to turn that least significant
.{ADD,SUB}_OVERFLOW call into .U{ADD,SUB}C call with 0 carry-in if
a more significant limb above it is matched into .U{ADD,SUB}C; this
isn't necessary for functionality, as .ADD_OVERFLOW (x, y) is
functionally equal to .UADDC (x, y, 0) (provided the types of operands
are the same and result is complex type with that type element), and
it also has code to match the most significant limb with ignored carry-out
(in that case one pattern match turns both the penultimate limb pair of
.{ADD,SUB}_OVERFLOW into .U{ADD,SUB}C and the addition/subtraction
of the 4 values (2 carries) into another .U{ADD,SUB}C.
As the following patch shows, what we weren't handling is the case when
one uses either the __builtin_{add,sub}c builtins or hand written forms
thereof (either __builtin_*_overflow or even that written by hand) for
just 2 limbs, where the least significant has 0 carry-in and the most
significant ignores carry-out. The following patch matches that, e.g.
_16 = .ADD_OVERFLOW (_1, _2);
_17 = REALPART_EXPR <_16>;
_18 = IMAGPART_EXPR <_16>;
_15 = _3 + _4;
_12 = _15 + _18;
into
_16 = .UADDC (_1, _2, 0);
_17 = REALPART_EXPR <_16>;
_18 = IMAGPART_EXPR <_16>;
_19 = .UADDC (_3, _4, _18);
_12 = IMAGPART_EXPR <_19>;
so that we can emit better code.
As the 2 later comments show, we must do that carefully, because the
pass walks the IL from first to last stmt in a bb and we must avoid
pattern matching this way something that should be matched on a later
instruction differently.
2023-08-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/79173
PR middle-end/111209
* tree-ssa-math-opts.cc (match_uaddc_usubc): Match also
just 2 limb uaddc/usubc with 0 carry-in on lower limb and ignored
carry-out on higher limb. Don't match it though if it could be
matched later on 4 argument addition/subtraction.
* gcc.target/i386/pr79173-12.c: New test.
Diffstat (limited to 'MAINTAINERS')
0 files changed, 0 insertions, 0 deletions