/* Simplify ~X & X as zero. */
(simplify
(bit_and (convert? @0) (convert? @1))
- (if (bitwise_inverted_equal_p (@0, @1))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+ && bitwise_inverted_equal_p (@0, @1))
{ build_zero_cst (type); }))
/* PR71636: Transform x & ((1U << b) - 1) -> x & ~(~0U << b); */
(for op (bit_ior bit_xor)
(simplify
(op (convert? @0) (convert? @1))
- (if (bitwise_inverted_equal_p (@0, @1))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+ && bitwise_inverted_equal_p (@0, @1))
(convert { build_all_ones_cst (TREE_TYPE (@0)); }))))
/* x ^ x -> 0 */
--- /dev/null
+/* We used to simplify these incorrectly. */
+__attribute__((noipa))
+long long
+foo (unsigned int x)
+{
+ int y = x;
+ y = ~y;
+ return ((long long) x) & y;
+}
+
+__attribute__((noipa))
+long long
+foo_v (volatile unsigned int x)
+{
+ volatile int y = x;
+ y = ~y;
+ return ((long long) x) & y;
+}
+
+__attribute__((noipa))
+long long
+bar (unsigned int x)
+{
+ int y = x;
+ y = ~y;
+ return ((long long) x) ^ y;
+}
+
+__attribute__((noipa))
+long long
+bar_v (volatile unsigned int x)
+{
+ volatile int y = x;
+ y = ~y;
+ return ((long long) x) ^ y;
+}
+
+__attribute__((noipa))
+long long
+baz (unsigned int x)
+{
+ int y = x;
+ y = ~y;
+ return y ^ ((long long) x);
+}
+
+__attribute__((noipa))
+long long
+baz_v (volatile unsigned int x)
+{
+ volatile int y = x;
+ y = ~y;
+ return y ^ ((long long) x);
+}
+
+
+int main()
+{
+ for(int t = -1; t <= 1; t++)
+ {
+ if (foo(t) != foo_v(t))
+ __builtin_abort ();
+ if (bar(t) != bar_v(t))
+ __builtin_abort ();
+ if (baz(t) != baz_v(t))
+ __builtin_abort ();
+ }
+}