fold-const.c (tree_expr_nonzero_p): Make non-static.
authorNaveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
Wed, 23 Nov 2016 10:29:18 +0000 (10:29 +0000)
committerNaveen H.S <naveenh@gcc.gnu.org>
Wed, 23 Nov 2016 10:29:18 +0000 (10:29 +0000)
2016-11-23  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

gcc
* fold-const.c (tree_expr_nonzero_p) : Make non-static.
* fold-const.h (tree_expr_nonzero_p) : Declare.
* match.pd (cmp (mult:c @0 @1) (mult:c @2 @1) : New Pattern.

gcc/testsuite
* gcc.dg/pr31096.c: New testcase.
* gcc.dg/pr31096-1.c: New testcase.

From-SVN: r242744

gcc/ChangeLog
gcc/fold-const.c
gcc/fold-const.h
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr31096-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr31096.c [new file with mode: 0644]

index b4e5acf..30ab26a 100644 (file)
@@ -1,3 +1,9 @@
+2016-11-23  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
+
+       * fold-const.c (tree_expr_nonzero_p) : Make non-static.
+       * fold-const.h (tree_expr_nonzero_p) : Declare.
+       * match.pd (cmp (mult:c @0 @1) (mult:c @2 @1) : New Pattern.
+
 2016-11-23  Paolo Bonzini  <bonzini@gnu.org>
 
        * system.h (HAVE_DESIGNATED_INITIALIZERS,
index 3c5a77e..a0055c4 100644 (file)
@@ -9014,7 +9014,7 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
 /* Return true when T is an address and is known to be nonzero.
    Handle warnings about undefined signed overflow.  */
 
-static bool
+bool
 tree_expr_nonzero_p (tree t)
 {
   bool ret, strict_overflow_p;
index 46dcd28..fbe1328 100644 (file)
@@ -169,6 +169,7 @@ extern tree size_diffop_loc (location_t, tree, tree);
 #define non_lvalue(T) non_lvalue_loc (UNKNOWN_LOCATION, T)
 extern tree non_lvalue_loc (location_t, tree);
 
+extern bool tree_expr_nonzero_p (tree);
 extern bool tree_expr_nonnegative_p (tree);
 extern bool tree_expr_nonnegative_warnv_p (tree, bool *, int = 0);
 extern tree make_range (tree, int *, tree *, tree *, bool *);
index 36270d0..3fece35 100644 (file)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
    zerop
    CONSTANT_CLASS_P
    tree_expr_nonnegative_p
+   tree_expr_nonzero_p
    integer_valued_real_p
    integer_pow2p
    HONOR_NANS)
@@ -1035,7 +1036,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && tree_nop_conversion_p (type, TREE_TYPE (@1)))
   (convert (bit_and (bit_not @1) @0))))
 
+/* For integral types with undefined overflow and C != 0 fold
+   x * C EQ/NE y * C into x EQ/NE y.  */
+(for cmp (eq ne)
+ (simplify
+  (cmp (mult:c @0 @1) (mult:c @2 @1))
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+       && tree_expr_nonzero_p (@1))
+   (cmp @0 @2))))
+
+/* For integral types with undefined overflow and C != 0 fold
+   x * C RELOP y * C into:
 
+   x RELOP y for nonnegative C
+   y RELOP x for negative C  */
+(for cmp (lt gt le ge)
+ (simplify
+  (cmp (mult:c @0 @1) (mult:c @2 @1))
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+   (if (tree_expr_nonnegative_p (@1) && tree_expr_nonzero_p (@1))
+    (cmp @0 @2)
+   (if (TREE_CODE (@1) == INTEGER_CST
+       && wi::neg_p (@1, TYPE_SIGN (TREE_TYPE (@1))))
+    (cmp @2 @0))))))
 
 /* ((X inner_op C0) outer_op C1)
    With X being a tree where value_range has reasoned certain bits to always be
index b9ccccc..47dadd8 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-23  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
+
+       * gcc.dg/pr31096.c: New testcase.
+       * gcc.dg/pr31096-1.c: New testcase.
+
 2016-11-23  Paolo Bonzini  <bonzini@gnu.org>
 
        * gcc.dg/cpp/defined.c: Mark newly introduced warnings and
diff --git a/gcc/testsuite/gcc.dg/pr31096-1.c b/gcc/testsuite/gcc.dg/pr31096-1.c
new file mode 100644 (file)
index 0000000..e681f0f
--- /dev/null
@@ -0,0 +1,51 @@
+/* PR middle-end/31096 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#define zero(name, op) \
+int name (int a, int b) \
+{ return a * 0 op b * 0; }
+
+zero(zeq, ==) zero(zne, !=) zero(zlt, <)
+zero(zgt, >)  zero(zge, >=) zero(zle, <=)
+
+#define unsign_pos(name, op) \
+int name (unsigned a, unsigned b) \
+{ return a * 4 op b * 4; }
+
+unsign_pos(upeq, ==) unsign_pos(upne, !=) unsign_pos(uplt, <)
+unsign_pos(upgt, >)  unsign_pos(upge, >=) unsign_pos(uple, <=)
+
+#define unsign_neg(name, op) \
+int name (unsigned a, unsigned b) \
+{ return a * -2 op b * -2; }
+
+unsign_neg(uneq, ==) unsign_neg(unne, !=) unsign_neg(unlt, <)
+unsign_neg(ungt, >)  unsign_neg(unge, >=) unsign_neg(unle, <=)
+
+#define float(name, op) \
+int name (float a, float b) \
+{ return a * 5 op b * 5; }
+
+float(feq, ==) float(fne, !=) float(flt, <)
+float(fgt, >)  float(fge, >=) float(fle, <=)
+
+#define float_val(name, op) \
+int name (int a, int b) \
+{ return a * 54.0 op b * 54.0; }
+
+float_val(fveq, ==) float_val(fvne, !=) float_val(fvlt, <)
+float_val(fvgt, >)  float_val(fvge, >=) float_val(fvle, <=)
+
+#define vec(name, op) \
+int name (int a, int b) \
+{ int c[10]; return a * c[1] op b * c[1]; }
+
+vec(veq, ==) vec(vne, !=) vec(vlt, <)
+vec(vgt, >)  vec(vge, >=) vec(vle, <=)
+
+/* { dg-final { scan-tree-dump-times "\\(D\\) \\* 4" 24 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\(D\\) \\* 4294967294" 12 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\(D\\) \\* 5\\.0e\\+0" 12 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\* 5\\.4e\\+1" 12 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\(D\\) \\* c\\\$1_8\\(D\\)" 12 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr31096.c b/gcc/testsuite/gcc.dg/pr31096.c
new file mode 100644 (file)
index 0000000..32c979e
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR middle-end/31096 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#define signval_pos(name, op) \
+int name (int a, int b) \
+{ return a * 4 op b * 4; }
+
+signval_pos(peq, ==) signval_pos(pne, !=) signval_pos(plt, <)
+signval_pos(pgt, >)  signval_pos(pge, >=) signval_pos(ple, <=)
+
+#define signval_neg(name, op) \
+int name (int a, int b) \
+{ return a * -23 op b * -23; }
+
+signval_neg(neq, ==) signval_neg(nne, !=) signval_neg(nlt, <)
+signval_neg(ngt, >)  signval_neg(nge, >=) signval_neg(nle, <=)
+
+#define vec_pos(name, op) \
+int name (int a[10], int b[10]) \
+{ return a[3] * 4 op b[8] * 4; }
+
+vec_pos(vpeq, ==) vec_pos(vpne, !=) vec_pos(vplt, <)
+vec_pos(vpgt, >)  vec_pos(vpge, >=) vec_pos(vple, <=)
+
+#define vec_neg(name, op) \
+int name (int a[10], int b[10]) \
+{ return a[3] * -23 op b[8] * -23; }
+
+vec_neg(vneq, ==) vec_neg(vnne, !=) vec_neg(vnlt, <)
+vec_neg(vngt, >)  vec_neg(vnge, >=) vec_neg(vnle, <=)
+
+/* { dg-final { scan-tree-dump-not "\\(D\\) \\* 4" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "\\(D\\) \\* -23" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "_1 = b_2\\(D\\)" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "_1 = MEM\\\[\\(int \\*\\)b" 4 "optimized" } } */