]> git.ipfire.org Git - thirdparty/gcc.git/commit
__builtin_<add/sub>_overflow issues on AArch64 (redux)
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Jan 2019 15:18:05 +0000 (15:18 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Jan 2019 15:18:05 +0000 (15:18 +0000)
commit8a4481bea34b128454f8acbdf124c4c0298c9ddc
tree2785ce519759fd3b5a125bedc0c626edbf82ba4b
parentc84c150f652615b701216e3e84466d93fad8216a
__builtin_<add/sub>_overflow issues on AArch64 (redux)

Further investigation showed that my previous patch for this issue was
still incomplete.

The problem stemmed from what I suspect was a mis-understanding of the
way overflow is calculated on aarch64 when values are subtracted (and
hence in comparisons).  In this case, unlike addition, the carry flag
is /cleared/ if there is overflow (technically, underflow) and set
when that does not happen.  This patch clears up this issue by using
CCmode for all subtractive operations (this can fully describe the
normal overflow conditions without anything particularly fancy);
clears up the way we express normal unsigned overflow using CC_Cmode
(the result of a sum is less than one of the operands) and adds a new
mode, CC_ADCmode to handle expressing overflow of an add-with-carry
operation, where the standard idiom is no-longer sufficient to
describe the overflow condition.

PR target/86891
* config/aarch64/aarch64-modes.def: Add comment about how the carry
bit is set by add and compare.
(CC_ADC): New CC_MODE.
* config/aarch64/aarch64.c (aarch64_select_cc_mode): Use variables
to cache the code and mode of X.  Adjust the shape of a CC_Cmode
comparison.  Add detection for CC_ADCmode.
(aarch64_get_condition_code_1): Update code support for CC_Cmode.  Add
CC_ADCmode.
* config/aarch64/aarch64.md (uaddv<mode>4): Use LTU with CCmode.
(uaddvti4): Comparison result is in CC_ADCmode and the condition is GEU.
(add<mode>3_compareC_cconly_imm): Delete.  Merge into...
(add<mode>3_compareC_cconly): ... this.  Restructure the comparison
to eliminate the need for zero-extending the operands.
(add<mode>3_compareC_imm): Delete.  Merge into ...
(add<mode>3_compareC): ... this.  Restructure the comparison to
eliminate the need for zero-extending the operands.
(add<mode>3_carryin): Use LTU for the overflow detection.
(add<mode>3_carryinC): Use CC_ADCmode for the result of the carry out.
Reexpress comparison for overflow.
(add<mode>3_carryinC_zero): Update for change to add<mode>3_carryinC.
(add<mode>3_carryinC): Likewise.
(add<mode>3_carryinV): Use LTU for carry between partials.
* config/aarch64/predicates.md (aarch64_carry_operation): Update
handling of CC_Cmode and add CC_ADCmode.
(aarch64_borrow_operation): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@267971 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/config/aarch64/aarch64-modes.def
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/predicates.md