Use unsigned arithmetic for demoted vector plus/minus/mult (PR 88064)
commit6a1665ab8563bf6bbe6610cbed92ef2f7f20629d
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Dec 2018 15:53:03 +0000 (5 15:53 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Dec 2018 15:53:03 +0000 (5 15:53 +0000)
tree7d45b3f40f7f93cfdd99b2f8c29863d603d74206
parent7a4b4584b790e03509cd40579ef0fbdf81ad4f14
Use unsigned arithmetic for demoted vector plus/minus/mult (PR 88064)

As Jakub pointed out, if we narrow a plus, minus or mult operation based
on the number of bits that consumers need, we have to convert a signed
operation to an unsigned one in order to avoid new undefined behaviour.
This patch does that and generalises vect_convert_input and
vect_recog_over_widening_pattern to cope with the extra casts.
(The changes to both functions are covered by existing tests.)

2018-12-03  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR tree-optimization/88064
* tree-vect-patterns.c (vect_convert_input): Convert the result of
an existing cast if it has the right width but the wrong sign.
Do not test the signedness of the required result when
considering whether to split an existing cast; instead split to
a type with the same signedness as the source of the cast, then
convert it to the opposite signedness where necessary.
(vect_recog_over_widening_pattern): Handle sign changes between
the final PLUS_EXPR and the RSHIFT_EXPR.
(vect_recog_average_pattern): Use an unsigned operation when
truncating an addition, subtraction or multiplication.  Cast the
result back to the "real" signedness before promoting.

gcc/testsuite/
PR tree-optimization/88064
* gcc.dg/vect/vect-over-widen-23.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266829 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-over-widen-23.c [new file with mode: 0644]
gcc/tree-vect-patterns.c