gcc.dg/tree-ssa/ssa-dom-cse-2.c: xfail scan for mmix.
[gcc.git] / gcc / match.pd
index 2b8c37e690e88b88408a4655262ef1a38e2ee53f..c6ae7a7db7aee88b8d42669133ddfe3f70f8761f 100644 (file)
@@ -1109,6 +1109,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && !TYPE_SATURATING (type))
   (bit_ior @0 @1)))
 
+/* (x | y) - y -> (x & ~y) */
+(simplify
+ (minus (bit_ior:cs @0 @1) @1)
+ (bit_and @0 (bit_not @1)))
+
 /* (x | y) - (x ^ y) -> x & y */
 (simplify
  (minus (bit_ior @0 @1) (bit_xor @0 @1))
@@ -1139,6 +1144,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
  (bit_xor @0 @1))
 
+/* ((x & y) - (x | y)) - 1 -> ~(x ^ y) */
+(simplify
+ (plus (nop_convert1? (minus@2 (nop_convert2? (bit_and:c @0 @1))
+                              (nop_convert2? (bit_ior @0 @1))))
+       integer_all_onesp)
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (plus@2 (nop_convert2? (bit_and:c @0 @1))
+                               integer_all_onesp))
+       (nop_convert3? (bit_ior @0 @1)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (bit_and @0 @1))
+       (nop_convert2? (plus@2 (nop_convert3? (bit_ior:c @0 @1))
+                               integer_onep)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+
 /* ~x & ~y -> ~(x | y)
    ~x | ~y -> ~(x & y) */
 (for op (bit_and bit_ior)
@@ -6024,6 +6058,54 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (plus (CTZ:type @0) { build_one_cst (type); })))
 #endif
 
+(for ffs (BUILT_IN_FFS BUILT_IN_FFSL BUILT_IN_FFSLL
+         BUILT_IN_FFSIMAX)
+ /* __builtin_ffs (X) == 0 -> X == 0.
+    __builtin_ffs (X) == 6 -> (X & 63) == 32.  */
+ (for cmp (eq ne)
+  (simplify
+   (cmp (ffs@2 @0) INTEGER_CST@1)
+    (with { int prec = TYPE_PRECISION (TREE_TYPE (@0)); }
+     (switch
+      (if (integer_zerop (@1))
+       (cmp @0 { build_zero_cst (TREE_TYPE (@0)); }))
+      (if (tree_int_cst_sgn (@1) < 0 || wi::to_widest (@1) > prec)
+       { constant_boolean_node (cmp == NE_EXPR ? true : false, type); })
+      (if (single_use (@2))
+       (cmp (bit_and @0 { wide_int_to_tree (TREE_TYPE (@0),
+                                           wi::mask (tree_to_uhwi (@1),
+                                                     false, prec)); })
+           { wide_int_to_tree (TREE_TYPE (@0),
+                               wi::shifted_mask (tree_to_uhwi (@1) - 1, 1,
+                                                 false, prec)); }))))))
+
+ /* __builtin_ffs (X) > 6 -> X != 0 && (X & 63) == 0.  */
+ (for cmp (gt le)
+      cmp2 (ne eq)
+      cmp3 (eq ne)
+      bit_op (bit_and bit_ior)
+  (simplify
+   (cmp (ffs@2 @0) INTEGER_CST@1)
+    (with { int prec = TYPE_PRECISION (TREE_TYPE (@0)); }
+     (switch
+      (if (integer_zerop (@1))
+       (cmp2 @0 { build_zero_cst (TREE_TYPE (@0)); }))
+      (if (tree_int_cst_sgn (@1) < 0)
+       { constant_boolean_node (cmp == GT_EXPR ? true : false, type); })
+      (if (wi::to_widest (@1) >= prec)
+       { constant_boolean_node (cmp == GT_EXPR ? false : true, type); })
+      (if (wi::to_widest (@1) == prec - 1)
+       (cmp3 @0 { wide_int_to_tree (TREE_TYPE (@0),
+                                   wi::shifted_mask (prec - 1, 1,
+                                                     false, prec)); }))
+      (if (single_use (@2))
+       (bit_op (cmp2 @0 { build_zero_cst (TREE_TYPE (@0)); })
+              (cmp3 (bit_and @0
+                             { wide_int_to_tree (TREE_TYPE (@0),
+                                                 wi::mask (tree_to_uhwi (@1),
+                                                 false, prec)); })
+                    { build_zero_cst (TREE_TYPE (@0)); }))))))))
+
 /* Simplify:
 
      a = a1 op a2