&& (int_fits_type_p (@1, TREE_TYPE (@0))
|| tree_nop_conversion_p (TREE_TYPE (@0), type)))
|| types_match (@0, @1))
+ && !POINTER_TYPE_P (TREE_TYPE (@0))
+ && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE
/* ??? This transform conflicts with fold-const.cc doing
Convert (T)(x & c) into (T)x & (T)c, if c is an integer
constants (if x has signed type, the sign bit cannot be set
(if (GIMPLE
&& TREE_CODE (@1) != INTEGER_CST
&& tree_nop_conversion_p (type, TREE_TYPE (@2))
- && types_match (type, @0))
+ && types_match (type, @0)
+ && !POINTER_TYPE_P (TREE_TYPE (@0))
+ && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE)
(bitop @0 (convert @1)))))
(for bitop (bit_and bit_ior)
--- /dev/null
+/* PR tree-optimization/106878 */
+
+typedef __INTPTR_TYPE__ intptr_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
+int a;
+
+int
+foo (const int *c)
+{
+ uintptr_t d = ((intptr_t) c | (intptr_t) &a) & 65535 << 16;
+ intptr_t e = (intptr_t) c;
+ if (d != (e & 65535 << 16))
+ return 1;
+ return 0;
+}
case ROUND_MOD_EXPR:
case RDIV_EXPR:
case EXACT_DIV_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
/* Disallow pointer and offset types for many of the binary gimple. */
if (POINTER_TYPE_P (lhs_type)
|| TREE_CODE (lhs_type) == OFFSET_TYPE)
case MIN_EXPR:
case MAX_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
+ /* Continue with generic binary expression handling. */
+ break;
+
case BIT_AND_EXPR:
+ if (POINTER_TYPE_P (lhs_type)
+ && TREE_CODE (rhs2) == INTEGER_CST)
+ break;
+ /* Disallow pointer and offset types for many of the binary gimple. */
+ if (POINTER_TYPE_P (lhs_type)
+ || TREE_CODE (lhs_type) == OFFSET_TYPE)
+ {
+ error ("invalid types for %qs", code_name);
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
+ return true;
+ }
/* Continue with generic binary expression handling. */
break;
tree type2 = NULL_TREE;
bool strict_overflow_p = false;
candidates.truncate (0);
+ if (POINTER_TYPE_P (type1))
+ type1 = pointer_sized_int_node;
for (j = i; j; j = chains[j - 1])
{
tree type = TREE_TYPE (ranges[j - 1].exp);
strict_overflow_p |= ranges[j - 1].strict_overflow_p;
+ if (POINTER_TYPE_P (type))
+ type = pointer_sized_int_node;
if ((b % 4) == 3)
{
/* For the signed < 0 cases, the types should be
tree type = TREE_TYPE (ranges[j - 1].exp);
if (j == k)
continue;
+ if (POINTER_TYPE_P (type))
+ type = pointer_sized_int_node;
if ((b % 4) == 3)
{
if (!useless_type_conversion_p (type1, type))
op = r->exp;
continue;
}
- if (id == l)
+ if (id == l || POINTER_TYPE_P (TREE_TYPE (op)))
{
code = (b % 4) == 3 ? BIT_NOT_EXPR : NOP_EXPR;
g = gimple_build_assign (make_ssa_name (type1), code, op);
gimple_seq_add_stmt_without_update (&seq, g);
op = gimple_assign_lhs (g);
}
+ type1 = TREE_TYPE (ranges[k - 1].exp);
+ if (POINTER_TYPE_P (type1))
+ {
+ gimple *g
+ = gimple_build_assign (make_ssa_name (type1), NOP_EXPR, op);
+ gimple_seq_add_stmt_without_update (&seq, g);
+ op = gimple_assign_lhs (g);
+ }
candidates.pop ();
if (update_range_test (&ranges[k - 1], NULL, candidates.address (),
candidates.length (), opcode, ops, op,