TYPE_PRECISION (type)), 0))
(convert @0)))
+#if GIMPLE
+/* X / (1 << C) -> X /[ex] (1 << C) if the low C bits of X are clear. */
+(simplify
+ (trunc_div (with_possible_nonzero_bits2 @0) integer_pow2p@1)
+ (if (INTEGRAL_TYPE_P (type)
+ && !TYPE_UNSIGNED (type)
+ && wi::multiple_of_p (get_nonzero_bits (@0), wi::to_wide (@1), SIGNED))
+ (exact_div @0 @1)))
+#endif
/* (X /[ex] A) * A -> X. */
(simplify
--- /dev/null
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+int
+f1 (int x, int y)
+{
+ if ((x & 1) || (y & 1))
+ __builtin_unreachable ();
+ x /= 2;
+ y /= 2;
+ return x < y;
+}
+
+int
+f2 (void *ptr1, void *ptr2, void *ptr3)
+{
+ ptr1 = __builtin_assume_aligned (ptr1, 4);
+ ptr2 = __builtin_assume_aligned (ptr2, 4);
+ ptr3 = __builtin_assume_aligned (ptr3, 4);
+ intptr_t diff1 = (intptr_t) ptr1 - (intptr_t) ptr2;
+ intptr_t diff2 = (intptr_t) ptr1 - (intptr_t) ptr3;
+ diff1 /= 2;
+ diff2 /= 2;
+ return diff1 < diff2;
+}
+
+/* { dg-final { scan-tree-dump-not {<[a-z]*_div_expr,} "optimized" } } */
+/* { dg-final { scan-tree-dump-not {<rshift_expr,} "optimized" } } */