https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127504
Bug ID: 127504
Summary: `-cmp * b` -> `cmp ? -b : 0`
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: easyhack, missed-optimization
Severity: enhancement
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Target: riscv aarch64
Take:
```
int f(int a, int b)
{
int c = b != 10;
c = -c;
return a * c;
}
int f1(int a, int b)
{
int c = b != 10;
return -(a * c);
}
```
These both should produce the same code.
Both aarch64 and riscv (with zicond) produce better code for f1.
There is a pattern to handle (CMP * a) but none to handle ((-CMP) * a).
The pattern for CMP*a:
```
/* (m1 CMP m2) * d -> (m1 CMP m2) ? d : 0 */
(if (fold_before_rtl_expansion_p ())
(for cmp (tcc_comparison)
(simplify
(mult:c (convert (cmp@0 @1 @2)) @3)
(if (INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (TREE_TYPE (@0)))
(cond @0 @3 { build_zero_cst (type); })))
/* (-(m1 CMP m2)) & d -> (m1 CMP m2) ? d : 0 */
(simplify
(bit_and:c (negate (convert (cmp@0 @1 @2))) @3)
(if (INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (TREE_TYPE (@0)))
(cond @0 @3 { build_zero_cst (type); })))
)
)
```
So adding one for this case here would be useful. This could show up if you
are using -1 as a mask to emulate vector masks.