match.pd: Optimize X / bool_range_Y to X [PR96094]
authorJakub Jelinek <jakub@redhat.com>
Tue, 15 Dec 2020 21:43:46 +0000 (22:43 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 15 Dec 2020 21:43:46 +0000 (22:43 +0100)
When the divisor is bool or has [0, 1] range, as division by
0 is UB, the only remaining option in valid programs is division by 1,
so we can optimize X / bool_range_Y into X.

2020-12-15  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/96094
* match.pd (X / bool_range_Y -> X): New simplification.

* gcc.dg/tree-ssa/pr96094.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr96094.c [new file with mode: 0644]

index 8f3edfa..c7ee57d 100644 (file)
@@ -348,11 +348,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   /* But not for 0 / 0 so that we can get the proper warnings and errors.  */
   (if (!integer_zerop (@1))
    @0))
 /* X / -1 is -X.  */
+ /* X / -1 is -X.  */
  (simplify
-   (div @0 integer_minus_onep@1)
-   (if (!TYPE_UNSIGNED (type))
-    (negate @0)))
+  (div @0 integer_minus_onep@1)
+  (if (!TYPE_UNSIGNED (type))
+   (negate @0)))
+ /* X / bool_range_Y is X.  */ 
+ (simplify
+  (div @0 SSA_NAME@1)
+  (if (INTEGRAL_TYPE_P (type) && ssa_name_has_boolean_range (@1))
+   @0))
  /* X / X is one.  */
  (simplify
   (div @0 @0)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96094.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96094.c
new file mode 100644 (file)
index 0000000..fe9163d
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR tree-optimization/96094 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return 34;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return y_\[0-9]*\\\(D\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return \[^\n\r;]*;" 4 "optimized" } } */
+
+int
+foo (int x)
+{
+  if (x >= 2U)
+    return 34;
+  return 34 / x;
+}
+
+int
+bar (int x, int y)
+{
+  if (x >= 2U)
+    return y;
+  return y / x;
+}
+
+int
+baz (_Bool x)
+{
+  return 34 / x;
+}
+
+int
+qux (_Bool x, int y)
+{
+  return y / x;
+}