re PR tree-optimization/88274 (ICE in check, at tree-vrp.c:188)
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Nov 2018 23:27:23 +0000 (00:27 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 30 Nov 2018 23:27:23 +0000 (00:27 +0100)
PR tree-optimization/88274
* tree-ssa-reassoc.c (optimize_range_tests_xor,
optimize_range_tests_diff): If type has smaller precision than
corresponding mode or if it has non-standard min/max, compute
everything in a standard type for the precision.

From-SVN: r266701

gcc/ChangeLog
gcc/tree-ssa-reassoc.c

index f319daf14cf0a8a8276a0914a0dbe3e1a68cef47..a759eeb4695bf1ed719fcc7239109d7dce58de96 100644 (file)
@@ -1,5 +1,11 @@
 2018-11-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/88274
+       * tree-ssa-reassoc.c (optimize_range_tests_xor,
+       optimize_range_tests_diff): If type has smaller precision than
+       corresponding mode or if it has non-standard min/max, compute
+       everything in a standard type for the precision.
+
        PR testsuite/85368
        * params.def (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT): New param.
        * tree-ssa-ifcombine.c (ifcombine_ifandif): If
index 971d926e7895c8ebebe660dbc5bdc02372a46f2c..a9f45bfd891c65b32e2dd36506211c9c8a06ead2 100644 (file)
@@ -2537,8 +2537,23 @@ optimize_range_tests_xor (enum tree_code opcode, tree type,
   if (!tree_int_cst_equal (lowxor, highxor))
     return false;
 
+  exp = rangei->exp;
+  scalar_int_mode mode = as_a <scalar_int_mode> (TYPE_MODE (type));
+  int prec = GET_MODE_PRECISION (mode);
+  if (TYPE_PRECISION (type) < prec
+      || (wi::to_wide (TYPE_MIN_VALUE (type))
+         != wi::min_value (prec, TYPE_SIGN (type)))
+      || (wi::to_wide (TYPE_MAX_VALUE (type))
+         != wi::max_value (prec, TYPE_SIGN (type))))
+    {
+      type = build_nonstandard_integer_type (prec, TYPE_UNSIGNED (type));
+      exp = fold_convert (type, exp);
+      lowxor = fold_convert (type, lowxor);
+      lowi = fold_convert (type, lowi);
+      highi = fold_convert (type, highi);
+    }
   tem = fold_build1 (BIT_NOT_EXPR, type, lowxor);
-  exp = fold_build2 (BIT_AND_EXPR, type, rangei->exp, tem);
+  exp = fold_build2 (BIT_AND_EXPR, type, exp, tem);
   lowj = fold_build2 (BIT_AND_EXPR, type, lowi, tem);
   highj = fold_build2 (BIT_AND_EXPR, type, highi, tem);
   if (update_range_test (rangei, rangej, NULL, 1, opcode, ops, exp,
@@ -2581,7 +2596,16 @@ optimize_range_tests_diff (enum tree_code opcode, tree type,
   if (!integer_pow2p (tem1))
     return false;
 
-  type = unsigned_type_for (type);
+  scalar_int_mode mode = as_a <scalar_int_mode> (TYPE_MODE (type));
+  int prec = GET_MODE_PRECISION (mode);
+  if (TYPE_PRECISION (type) < prec
+      || (wi::to_wide (TYPE_MIN_VALUE (type))
+         != wi::min_value (prec, TYPE_SIGN (type)))
+      || (wi::to_wide (TYPE_MAX_VALUE (type))
+         != wi::max_value (prec, TYPE_SIGN (type))))
+    type = build_nonstandard_integer_type (prec, 1);
+  else
+    type = unsigned_type_for (type);
   tem1 = fold_convert (type, tem1);
   tem2 = fold_convert (type, tem2);
   lowi = fold_convert (type, lowi);