This makes us treat &a == &a in operand_equal_p in case the addresses
have TREE_CONSTANT set, even in the case if a has TREE_SIDE_EFFECTS
set (such as for volatile vars).  Simply special-casing DECLs in the
ADDR_EXPR case wouldn't handle &a.b == &a.b.

I think it's important that operand_equal_p (a, a, 0) holds if
a holds is_gimple_min_invariant (), as we generally compare
constants using it.  We could devise some other solution,
for example introducing a possibly cheaper gimple_val_equal_p ()
predicate that only handles operands that satisfy is_gimple_val ().

Any comments?

The testcase is too large, I didn't sofar try to construct one
artificially.

The issue is latent at least on the 4.6 branch.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2011-04-20  Richard Guenther  <rguent...@suse.de>

        * tree.h (OEP_CONSTANT_ADDRESS_OF): New operand_equal_flag.
        * fold-const.c (operand_equal_p): For TREE_CONSTANT ADDR_EXPRs
        compare the operands with OEP_CONSTANT_ADDRESS_OF.  Treat
        trees with TREE_SIDE_EFFECTS equal when OEP_CONSTANT_ADDRESS_OF
        is set.

Index: gcc/tree.h
===================================================================
*** gcc/tree.h  (revision 172759)
--- gcc/tree.h  (working copy)
*************** extern tree fold_fma (location_t, tree,
*** 5118,5124 ****
  enum operand_equal_flag
  {
    OEP_ONLY_CONST = 1,
!   OEP_PURE_SAME = 2
  };
  
  extern int operand_equal_p (const_tree, const_tree, unsigned int);
--- 5118,5125 ----
  enum operand_equal_flag
  {
    OEP_ONLY_CONST = 1,
!   OEP_PURE_SAME = 2,
!   OEP_CONSTANT_ADDRESS_OF = 4
  };
  
  extern int operand_equal_p (const_tree, const_tree, unsigned int);
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c    (revision 172759)
--- gcc/fold-const.c    (working copy)
*************** operand_equal_p (const_tree arg0, const_
*** 2475,2483 ****
       equal if they have no side effects.  If we have two identical
       expressions with side effects that should be treated the same due
       to the only side effects being identical SAVE_EXPR's, that will
!      be detected in the recursive calls below.  */
    if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
        && (TREE_CODE (arg0) == SAVE_EXPR
          || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
      return 1;
  
--- 2475,2486 ----
       equal if they have no side effects.  If we have two identical
       expressions with side effects that should be treated the same due
       to the only side effects being identical SAVE_EXPR's, that will
!      be detected in the recursive calls below.
!      If we are taking an invariant address of two identical objects
!      they are necessarily equal as well.  */
    if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
        && (TREE_CODE (arg0) == SAVE_EXPR
+         || (flags & OEP_CONSTANT_ADDRESS_OF)
          || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
      return 1;
  
*************** operand_equal_p (const_tree arg0, const_
*** 2540,2546 ****
  
        case ADDR_EXPR:
        return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
!                               0);
        default:
        break;
        }
--- 2543,2550 ----
  
        case ADDR_EXPR:
        return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
!                               TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1)
!                               ? OEP_CONSTANT_ADDRESS_OF : 0);
        default:
        break;
        }

Reply via email to