diff options
author | Richard Guenther <rguenther@suse.de> | 2007-10-04 09:37:04 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-10-04 09:37:04 +0000 |
commit | dc5752338ba869ec407f1d97b0d47793be431239 (patch) | |
tree | e796856d793e5691b916e4fbbedc157a8e3dce8b /gcc/tree-gimple.c | |
parent | 65567efaa82178fcfe63bee2c81f06a541cd72a4 (diff) | |
download | gcc-dc5752338ba869ec407f1d97b0d47793be431239.zip gcc-dc5752338ba869ec407f1d97b0d47793be431239.tar.gz gcc-dc5752338ba869ec407f1d97b0d47793be431239.tar.bz2 |
re PR tree-optimization/33627 (ICE in verify_stmts compiling abiword)
2007-10-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/33627
* tree-gimple.h (canonicalize_cond_expr_cond): Declare.
* tree-gimple.c (canonicalize_cond_expr_cond): New function,
split out from ...
* tree-ssa-forwprop.c (combine_cond_expr_cond): ... here.
* tree-ssa-ifcombine.c (ifcombine_iforif): Use it.
* g++.dg/torture/pr33627.C: New testcase.
From-SVN: r129004
Diffstat (limited to 'gcc/tree-gimple.c')
-rw-r--r-- | gcc/tree-gimple.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 8e976e2..7b29812 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -521,3 +521,47 @@ recalculate_side_effects (tree t) gcc_unreachable (); } } + +/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns + a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if + we failed to create one. */ + +tree +canonicalize_cond_expr_cond (tree t) +{ + /* For (bool)x use x != 0. */ + if (TREE_CODE (t) == NOP_EXPR + && TREE_TYPE (t) == boolean_type_node) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (NE_EXPR, TREE_TYPE (t), + top0, build_int_cst (TREE_TYPE (top0), 0)); + } + /* For !x use x == 0. */ + else if (TREE_CODE (t) == TRUTH_NOT_EXPR) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (EQ_EXPR, TREE_TYPE (t), + top0, build_int_cst (TREE_TYPE (top0), 0)); + } + /* For cmp ? 1 : 0 use cmp. */ + else if (TREE_CODE (t) == COND_EXPR + && COMPARISON_CLASS_P (TREE_OPERAND (t, 0)) + && integer_onep (TREE_OPERAND (t, 1)) + && integer_zerop (TREE_OPERAND (t, 2))) + { + tree top0 = TREE_OPERAND (t, 0); + t = build2 (TREE_CODE (top0), TREE_TYPE (t), + TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); + } + + /* A valid conditional for a COND_EXPR is either a gimple value + or a comparison with two gimple value operands. */ + if (is_gimple_val (t) + || (COMPARISON_CLASS_P (t) + && is_gimple_val (TREE_OPERAND (t, 0)) + && is_gimple_val (TREE_OPERAND (t, 1)))) + return t; + + return NULL_TREE; +} |