diff options
author | Tamar Christina <tamar.christina@arm.com> | 2023-10-18 09:32:55 +0100 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2023-10-18 09:53:47 +0100 |
commit | 4b39aeef594f311e2c1715f15608f1d7ebc2d868 (patch) | |
tree | bc0f36b93c71bb595b54948fd82d3ecc4cc6bb7d /gcc/rust/ast/rust-pattern.h | |
parent | b588dcb77e96d77777eb5647cba9e8f454e314dc (diff) | |
download | gcc-4b39aeef594f311e2c1715f15608f1d7ebc2d868.zip gcc-4b39aeef594f311e2c1715f15608f1d7ebc2d868.tar.gz gcc-4b39aeef594f311e2c1715f15608f1d7ebc2d868.tar.bz2 |
middle-end: Fold vec_cond into conditional ternary or binary operation when sharing operand [PR109154]
When we have a vector conditional on a masked target which is doing a selection
on the result of a conditional operation where one of the operands of the
conditional operation is the other operand of the select, then we can fold the
vector conditional into the operation.
Concretely this transforms
c = mask1 ? (masked_op mask2 a b) : b
into
c = masked_op (mask1 & mask2) a b
The mask is then propagated upwards by the compiler. In the SVE case we don't
end up needing a mask AND here since `mask2` will end up in the instruction
creating `mask` which gives us a natural &.
Such transformations are more common now in GCC 13+ as PRE has not started
unsharing of common code in case it can make one branch fully independent.
e.g. in this case `b` becomes a loop invariant value after PRE.
This transformation removes the extra select for masked architectures but
doesn't fix the general case.
gcc/ChangeLog:
PR tree-optimization/109154
* match.pd: Add new cond_op rule.
gcc/testsuite/ChangeLog:
PR tree-optimization/109154
* gcc.target/aarch64/sve/pre_cond_share_1.c: New test.
Diffstat (limited to 'gcc/rust/ast/rust-pattern.h')
0 files changed, 0 insertions, 0 deletions