diff --git a/gcc/match.pd b/gcc/match.pd
index 04033546fc1..5270e4104ac 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -172,6 +172,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 )
 #endif
 
+/* Try simple folding for X op !X, and X op X with the help
+   of the truth_valued_p and logical_inverted_value predicates.  */
+(match truth_valued_p
+ @0
+ (if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1)))
+(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor)
+ (match truth_valued_p
+  (op @0 @1)))
+(match truth_valued_p
+  (truth_not @0))
+
+/* zero_one_valued_p will match when a value is known to be either
+   0 or 1 including constants 0 or 1.
+   Signed 1-bits includes -1 so they cannot match here. */
+/* Note ssa_name_has_boolean_range uses
+   the current ranger while tree_nonzero_bits uses only
+   the global one. */
+(match zero_one_valued_p
+ SSA_NAME@0
+ (if (ssa_name_has_boolean_range (@0))))
+(match zero_one_valued_p
+ @0
+ (if (INTEGRAL_TYPE_P (type)
+      && (TYPE_UNSIGNED (type)
+	  || TYPE_PRECISION (type) > 1)
+      && wi::leu_p (tree_nonzero_bits (@0), 1))))
+(match zero_one_valued_p
+ truth_valued_p@0
+ (if (INTEGRAL_TYPE_P (type)
+      && (TYPE_UNSIGNED (type)
+	  || TYPE_PRECISION (type) > 1))))
+
 /* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR <x>
    ABSU_EXPR returns unsigned absolute value of the operand and the operand
    of the ABSU_EXPR will have the corresponding signed type.  */
@@ -493,13 +525,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (div @0 integer_minus_onep@1)
   (if (!TYPE_UNSIGNED (type))
    (negate @0)))
- /* X / bool_range_Y is X.  */ 
- (simplify
-  (div @0 SSA_NAME@1)
-  (if (INTEGRAL_TYPE_P (type)
-       && ssa_name_has_boolean_range (@1)
-       && !flag_non_call_exceptions)
-   @0))
  /* X / X is one.  */
  (simplify
   (div @0 @0)
@@ -525,7 +550,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	&& TYPE_OVERFLOW_UNDEFINED (type)
 	&& !integer_zerop (@0)
 	&& (!flag_non_call_exceptions || tree_expr_nonzero_p (@0)))
-    { build_minus_one_cst (type); })))
+    { build_minus_one_cst (type); }))
+ /* X / bool_range_Y is X.  */
+ (simplify
+  (div @0 zero_one_valued_p@1)
+  (if (INTEGRAL_TYPE_P (type)
+       /* But not for X / 0 so that we can get the proper warnings and errors. */
+       && !integer_zerop (@1)
+       && !flag_non_call_exceptions)
+   @0)))
 
 /* For unsigned integral types, FLOOR_DIV_EXPR is the same as
    TRUNC_DIV_EXPR.  Rewrite into the latter in this case.  Similarly
@@ -1865,14 +1898,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (plus @0 (negate @1))))
 
 /* 1 - a is a ^ 1 if a had a bool range. */
-/* This is only enabled for gimple as sometimes
-   cfun is not set for the function which contains
-   the SSA_NAME (e.g. while IPA passes are happening,
-   fold might be called).  */
 (simplify
- (minus integer_onep@0 SSA_NAME@1)
-  (if (INTEGRAL_TYPE_P (type)
-       && ssa_name_has_boolean_range (@1))
+ (minus integer_onep@0 zero_one_valued_p@1)
+  (if (INTEGRAL_TYPE_P (type))
    (bit_xor @1 @0)))
 
 /* Other simplifications of negation (c.f. fold_negate_expr_1).  */
@@ -2018,17 +2046,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (if (cst2)
        (bitop @0 { cst2; }))))))))
 
-/* Try simple folding for X op !X, and X op X with the help
-   of the truth_valued_p and logical_inverted_value predicates.  */
-(match truth_valued_p
- @0
- (if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1)))
-(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor)
- (match truth_valued_p
-  (op @0 @1)))
-(match truth_valued_p
-  (truth_not @0))
-
 (match (logical_inverted_value @0)
  (truth_not @0))
 (match (logical_inverted_value @0)
@@ -2060,27 +2077,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (bit_not (bit_not @0))
   @0)
 
-/* zero_one_valued_p will match when a value is known to be either
-   0 or 1 including constants 0 or 1.
-   Signed 1-bits includes -1 so they cannot match here. */
-/* Note ssa_name_has_boolean_range uses
-   the current ranger while tree_nonzero_bits uses only
-   the global one. */
-(match zero_one_valued_p
- SSA_NAME@0
- (if (ssa_name_has_boolean_range (@0))))
-(match zero_one_valued_p
- @0
- (if (INTEGRAL_TYPE_P (type)
-      && (TYPE_UNSIGNED (type)
-	  || TYPE_PRECISION (type) > 1)
-      && wi::leu_p (tree_nonzero_bits (@0), 1))))
-(match zero_one_valued_p
- truth_valued_p@0
- (if (INTEGRAL_TYPE_P (type)
-      && (TYPE_UNSIGNED (type)
-	  || TYPE_PRECISION (type) > 1))))
-
 /* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }.  */
 (simplify
  (mult zero_one_valued_p@0 zero_one_valued_p@1)
@@ -5486,12 +5482,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* -(type)!A -> (type)A - 1.  */
 (simplify
- (negate (convert?:s (logical_inverted_value:s @0)))
+ (negate (convert?:s (logical_inverted_value:s zero_one_valued_p@0)))
  (if (INTEGRAL_TYPE_P (type)
       && TREE_CODE (type) != BOOLEAN_TYPE
-      && TYPE_PRECISION (type) > 1
-      && TREE_CODE (@0) == SSA_NAME
-      && ssa_name_has_boolean_range (@0))
+      && TYPE_PRECISION (type) > 1)
   (plus (convert:type @0) { build_all_ones_cst (type); })))
 
 /* A + (B vcmp C ? 1 : 0) -> A - (B vcmp C ? -1 : 0), since vector comparisons
