+2016-11-20 Marc Glisse <marc.glisse@inria.fr>
+
+ * fold-const.c (fold_comparison): Ignore EXACT_DIV_EXPR.
+ * match.pd (A /[ex] B CMP C): New simplifications.
+
2016-11-20 Marc Glisse <marc.glisse@inria.fr>
* match.pd (0 / X, X / X, X % X): New simplifications.
/* We can fold X/C1 op C2 where C1 and C2 are integer constants
into a single range test. */
- if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
- || TREE_CODE (arg0) == EXACT_DIV_EXPR)
+ if (TREE_CODE (arg0) == TRUNC_DIV_EXPR
&& TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
&& !integer_zerop (TREE_OPERAND (arg0, 1))
(ge @0 { build_real (TREE_TYPE (@0), dconst0); })
(cmp @0 { build_real (TREE_TYPE (@0), c2); }))))))))))))
+/* Fold A /[ex] B CMP C to A CMP B * C. */
+(for cmp (eq ne)
+ (simplify
+ (cmp (exact_div @0 @1) INTEGER_CST@2)
+ (if (!integer_zerop (@1))
+ (if (wi::eq_p (@2, 0))
+ (cmp @0 @2)
+ (if (TREE_CODE (@1) == INTEGER_CST)
+ (with
+ {
+ bool ovf;
+ wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf);
+ }
+ (if (ovf)
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); }))))))))
+(for cmp (lt le gt ge)
+ (simplify
+ (cmp (exact_div @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (wi::gt_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1))))
+ (with
+ {
+ bool ovf;
+ wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf);
+ }
+ (if (ovf)
+ { constant_boolean_node (wi::lt_p (@2, 0, TYPE_SIGN (TREE_TYPE (@2)))
+ != (cmp == LT_EXPR || cmp == LE_EXPR), type); }
+ (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); }))))))
+
/* Unordered tests if either argument is a NaN. */
(simplify
(bit_ior (unordered @0 @0) (unordered @1 @1))
+2016-11-20 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/cmpexactdiv.c: New file.
+
2016-11-20 Andre Vehreschild <vehre@gcc.gnu.org>
PR fortran/78395
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int f(int *p, int *q){
+ __SIZE_TYPE__ n = q - p;
+ return n == 0;
+}
+
+int g(int *p, int *q){
+ __PTRDIFF_TYPE__ n = q - p;
+ return n <= 2;
+}
+
+int h(long *p, long *q){
+ __SIZE_TYPE__ n = q - p;
+ return n == (__SIZE_TYPE__)(-1)/2;
+}
+
+/* { dg-final { scan-tree-dump-not "== 0" "optimized" } } */
+/* { dg-final { scan-tree-dump "<= 8" "optimized" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump "return 0" "optimized" } } */