aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenth@gcc.gnu.org>2005-04-26 16:35:31 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2005-04-26 16:35:31 +0000
commit70a390bbb670c358e1f933ef8e75a3a3d7ca8fa5 (patch)
tree75a85c6c78844dca9ea04acfe5326683bc8d8c99 /gcc/fold-const.c
parent866af8a90915d8ed191ab7af616b3a186c28cae4 (diff)
downloadgcc-70a390bbb670c358e1f933ef8e75a3a3d7ca8fa5.zip
gcc-70a390bbb670c358e1f933ef8e75a3a3d7ca8fa5.tar.gz
gcc-70a390bbb670c358e1f933ef8e75a3a3d7ca8fa5.tar.bz2
re PR tree-optimization/17598 (an extra addition when comparing address of &a->b and &c->b.)
2004-04-26 Richard Guenther <rguenth@gcc.gnu.org> PR tree-optimization/17598 * fold-const.c (fold_binary): Fold comparisons of addresses of COMPONENT_REFs which reference the same field to comparisons of the addresses of the base objects. * gcc.dg/tree-ssa/pr17598.c: New testcase. From-SVN: r98775
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 416d89e..9de988c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9708,6 +9708,39 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
return t1;
}
+ /* Fold a comparison of the address of COMPONENT_REFs with the same
+ type and component to a comparison of the address of the base
+ object. In short, &x->a OP &y->a to x OP y and
+ &x->a OP &y.a to x OP &y */
+ if (TREE_CODE (arg0) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == COMPONENT_REF
+ && TREE_CODE (arg1) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (arg1, 0)) == COMPONENT_REF)
+ {
+ tree cref0 = TREE_OPERAND (arg0, 0);
+ tree cref1 = TREE_OPERAND (arg1, 0);
+ if (TREE_OPERAND (cref0, 1) == TREE_OPERAND (cref1, 1))
+ {
+ tree op0 = TREE_OPERAND (cref0, 0);
+ tree op1 = TREE_OPERAND (cref1, 0);
+ if (TREE_CODE (op0) == INDIRECT_REF)
+ op0 = TREE_OPERAND (op0, 0);
+ else
+ {
+ tree ptype = build_pointer_type (TREE_TYPE (op0));
+ op0 = build1 (ADDR_EXPR, ptype, op0);
+ }
+ if (TREE_CODE (op1) == INDIRECT_REF)
+ op1 = TREE_OPERAND (op1, 0);
+ else
+ {
+ tree ptype = build_pointer_type (TREE_TYPE (op1));
+ op1 = build1 (ADDR_EXPR, ptype, op1);
+ }
+ return fold_build2 (code, type, op0, op1);
+ }
+ }
+
/* If this is a comparison of complex values and either or both sides
are a COMPLEX_EXPR or COMPLEX_CST, it is best to split up the
comparisons and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR.