From: Kyrylo Tkachov <[email protected]>
This is the testcases from
https://gcc.gnu.org/pipermail/gcc-patches/2026-July/724647.html
which I was going to add but missed previouisly.
Note I had to move the check from phiopt2 to phiopt4 for
phiopt-neg-bool-mask-1.c
until factoring can handle unconditional single use expressions.
Tested on x86_64-linux-gnu.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c: New test.
* gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c: Likewise.
Signed-off-by: Kyrylo Tkachov <[email protected]>
Signed-off-by: Andrea Pinski <[email protected]>
---
.../gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c | 42 +++++++++++++++++++
.../gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c | 36 ++++++++++++++++
2 files changed, 78 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c
b/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c
new file mode 100644
index 00000000000..e7f241b105d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+int
+direct_negative_mask (int outer, int value)
+{
+ int mask = -(value > 0);
+ return outer > 0 ? mask : 0;
+}
+
+int
+direct_negative_mask_minus_one (int outer, int value)
+{
+ int mask = -(value > 0);
+ return outer > 0 ? mask : -1;
+}
+
+unsigned int
+direct_negative_mask_unsigned (int outer, int value)
+{
+ unsigned int mask = -(unsigned int) (value > 0);
+ return outer > 0 ? mask : 0;
+}
+
+unsigned int
+direct_negative_mask_minus_one_unsigned (int outer, int value)
+{
+ unsigned int mask = -(unsigned int) (value > 0);
+ return outer > 0 ? mask : -1U;
+}
+
+/* This happen in phiopt2 but currently this depends on the
+ sink pass to make operations conditional. */
+
+/* The zero else arms contribute two AND operations. */
+/* { dg-final { scan-tree-dump-times " & " 2 "phiopt4" } } */
+/* { dg-final { scan-tree-dump-times " & " 2 "phiopt2" { xfail *-*-* } } } */
+/* The minus-one else arms contribute two OR operations. */
+/* { dg-final { scan-tree-dump-times " \\| " 2 "phiopt2" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times " \\| " 2 "phiopt4" } } */
+/* { dg-final { scan-tree-dump-not "if \\(" "phiopt2" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-not "if \\(" "phiopt4" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c
b/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c
new file mode 100644
index 00000000000..421d31de6ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiopt-neg-bool-mask-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fgimple" } */
+
+/* Do not use an arbitrary negated operand as a numeric zero-one value in the
+ mask identities. */
+
+__attribute__ ((noipa)) int __GIMPLE ()
+zero_else_non_boolean_value (_Bool c, int b)
+{
+ int nb;
+ int r;
+
+ nb = -b_2(D);
+ r = c_1(D) ? nb : 0;
+ return r;
+}
+
+__attribute__ ((noipa)) int __GIMPLE ()
+minus_one_else_non_boolean_value (_Bool c, int b)
+{
+ int nb;
+ int r;
+
+ nb = -b_2(D);
+ r = c_1(D) ? nb : _Literal (int) -1;
+ return r;
+}
+
+int
+main (void)
+{
+ if (zero_else_non_boolean_value (1, 2) != -2
+ || minus_one_else_non_boolean_value (0, 2) != -1)
+ __builtin_abort ();
+ return 0;
+}
--
2.43.0