fold-const.c (fold_binary_loc): Move Convert A/B/C to A/(B*C) to match.pd.
authorNaveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
Thu, 12 Nov 2015 05:34:54 +0000 (05:34 +0000)
committerNaveen H.S <naveenh@gcc.gnu.org>
Thu, 12 Nov 2015 05:34:54 +0000 (05:34 +0000)
2015-11-12  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

* fold-const.c (fold_binary_loc) : Move Convert A/B/C to A/(B*C)
to match.pd.
Move Convert A/(B/C) to (A/B)*C to match.pd.
Move Convert C1/(X*C2) into (C1/C2)/X to match.pd.
Move Optimize (X & (-A)) / A where A is a power of 2, to
X >> log2(A) to match.pd.

* match.pd (rdiv (rdiv:s @0 @1) @2): New simplifier.
(rdiv @0 (rdiv:s @1 @2)): New simplifier.
(div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2):
New simplifier.
(rdiv REAL_CST@0 (mult @1 REAL_CST@2)): New simplifier.

From-SVN: r230204

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd

index 91ad0996d2218d31506ec7b6d95f66d606645603..5c0d9f67ad8f6ad6376f6f47381db343c329eace 100644 (file)
@@ -1,3 +1,18 @@
+2015-11-12  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
+
+       * fold-const.c (fold_binary_loc) : Move Convert A/B/C to A/(B*C)
+       to match.pd.
+       Move Convert A/(B/C) to (A/B)*C to match.pd.
+       Move Convert C1/(X*C2) into (C1/C2)/X to match.pd.
+       Move Optimize (X & (-A)) / A where A is a power of 2, to
+       X >> log2(A) to match.pd.
+       
+       * match.pd (rdiv (rdiv:s @0 @1) @2): New simplifier.
+       (rdiv @0 (rdiv:s @1 @2)): New simplifier.
+       (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2):
+       New simplifier.
+       (rdiv REAL_CST@0 (mult @1 REAL_CST@2)): New simplifier.
+
 2015-11-12  Charles Baylis  <charles.baylis@linaro.org>
 
        * config/arm/neon.md: (neon_vld2_lane<mode>): Remove unused max
index 8dc849c3606306bd8d6ec265ed467622961440ec..9114dec074adaacccffae8c44751d1a4fd05a498 100644 (file)
@@ -10195,54 +10195,9 @@ fold_binary_loc (location_t loc,
        return fold_build2_loc (loc, RDIV_EXPR, type,
                            negate_expr (arg0),
                            TREE_OPERAND (arg1, 0));
-
-      /* Convert A/B/C to A/(B*C).  */
-      if (flag_reciprocal_math
-         && TREE_CODE (arg0) == RDIV_EXPR)
-       return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-                           fold_build2_loc (loc, MULT_EXPR, type,
-                                        TREE_OPERAND (arg0, 1), arg1));
-
-      /* Convert A/(B/C) to (A/B)*C.  */
-      if (flag_reciprocal_math
-         && TREE_CODE (arg1) == RDIV_EXPR)
-       return fold_build2_loc (loc, MULT_EXPR, type,
-                           fold_build2_loc (loc, RDIV_EXPR, type, arg0,
-                                        TREE_OPERAND (arg1, 0)),
-                           TREE_OPERAND (arg1, 1));
-
-      /* Convert C1/(X*C2) into (C1/C2)/X.  */
-      if (flag_reciprocal_math
-         && TREE_CODE (arg1) == MULT_EXPR
-         && TREE_CODE (arg0) == REAL_CST
-         && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-       {
-         tree tem = const_binop (RDIV_EXPR, arg0,
-                                 TREE_OPERAND (arg1, 1));
-         if (tem)
-           return fold_build2_loc (loc, RDIV_EXPR, type, tem,
-                               TREE_OPERAND (arg1, 0));
-       }
-
       return NULL_TREE;
 
     case TRUNC_DIV_EXPR:
-      /* Optimize (X & (-A)) / A where A is a power of 2,
-        to X >> log2(A) */
-      if (TREE_CODE (arg0) == BIT_AND_EXPR
-         && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
-         && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
-       {
-         tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
-                                     arg1, TREE_OPERAND (arg0, 1));
-         if (sum && integer_zerop (sum)) {
-           tree pow2 = build_int_cst (integer_type_node,
-                                      wi::exact_log2 (arg1));
-           return fold_build2_loc (loc, RSHIFT_EXPR, type,
-                                   TREE_OPERAND (arg0, 0), pow2);
-         }
-       }
-
       /* Fall through */
       
     case FLOOR_DIV_EXPR:
index f6c5c07b681ae546039b682363154bc1854621a7..d552bebdafebd07642e5f4d4178e1e6146567a68 100644 (file)
@@ -247,6 +247,28 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!HONOR_SNANS (type))
   (negate @0)))
 
+(if (flag_reciprocal_math)
+ /* Convert (A/B)/C to A/(B*C)  */
+ (simplify
+  (rdiv (rdiv:s @0 @1) @2)
+   (rdiv @0 (mult @1 @2)))
+
+ /* Convert A/(B/C) to (A/B)*C  */
+ (simplify
+  (rdiv @0 (rdiv:s @1 @2))
+   (mult (rdiv @0 @1) @2)))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+  (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+  (if (integer_pow2p (@2)
+       && tree_int_cst_sgn (@2) > 0
+       && wi::add (@2, @1) == 0
+       && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (rshift (convert @0) { build_int_cst (integer_type_node,
+                                        wi::exact_log2 (@2)); }))))
+
 /* If ARG1 is a constant, we can convert this to a multiply by the
    reciprocal.  This does not have the same rounding properties,
    so only do this if -freciprocal-math.  We can actually
@@ -464,6 +486,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (tem)
      (rdiv { tem; } @1)))))
 
+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv REAL_CST@0 (mult @1 REAL_CST@2))
+  (if (flag_reciprocal_math)
+   (with
+    { tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+    (if (tem)
+     (rdiv { tem; } @1)))))
+
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and:c (convert? @0) (convert? (bit_not @0)))