gimple_bitwise_equal_p (expr1, expr2, valueize)
bool gimple_nop_convert (tree, tree *, tree (*) (tree));
+bool gimple_maybe_truncate (tree, tree *, tree (*) (tree));
/* Helper function for bitwise_equal_p macro. */
}
if (expr2 != expr4 && operand_equal_p (expr1, expr4, 0))
return true;
+ if (gimple_maybe_truncate (expr3, &expr3, valueize)
+ && gimple_maybe_truncate (expr4, &expr4, valueize)
+ && operand_equal_p (expr3, expr4, 0))
+ return true;
return false;
}
/* Try if EXPR1 was defined as ~EXPR2. */
if (gimple_bit_not_with_nop (expr1, &other, valueize))
{
- if (operand_equal_p (other, expr2, 0))
- return true;
- tree expr4;
- if (gimple_nop_convert (expr2, &expr4, valueize)
- && operand_equal_p (other, expr4, 0))
+ if (gimple_bitwise_equal_p (other, expr2, valueize))
return true;
}
/* Try if EXPR2 was defined as ~EXPR1. */
if (gimple_bit_not_with_nop (expr2, &other, valueize))
{
- if (operand_equal_p (other, expr1, 0))
- return true;
- tree expr3;
- if (gimple_nop_convert (expr1, &expr3, valueize)
- && operand_equal_p (other, expr3, 0))
+ if (gimple_bitwise_equal_p (other, expr1, valueize))
return true;
}
(match (maybe_bit_not @0)
(bit_xor_cst@0 @1 @2))
+#if GIMPLE
+(match (maybe_truncate @0)
+ (convert @0)
+ (if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@0)))))
+#endif
+
/* 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. */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/115449 */
+
+void setBit_un(unsigned char *a, int b) {
+ unsigned char c = 0x1UL << b;
+ *a &= ~c;
+ *a |= c;
+}
+
+void setBit_sign(signed char *a, int b) {
+ signed char c = 0x1UL << b;
+ *a &= ~c;
+ *a |= c;
+}
+
+void setBit(char *a, int b) {
+ char c = 0x1UL << b;
+ *a &= ~c;
+ *a |= c;
+}
+/*
+ All three should produce:
+ _1 = 1 << b_4(D);
+ c_5 = (cast) _1;
+ _2 = *a_7(D);
+ _3 = _2 | c_5;
+ *a_7(D) = _3;
+ Removing the `&~c` as we are matching `(~x & y) | x` -> `x | y`
+ match pattern even with extra casts are being involved. */
+
+/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_and_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 3 "optimized" } } */