On Thu, 2 Apr 2015, Richard Biener wrote: > > The following makes CCP track copies which avoids pass ordering > issues between CCP and copyprop as seen from the testcase. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1. > > For stage1 I'd like to get rid of copyprop completely, a 2nd patch > in the series will remove the copyprop instances immediately > preceeding/following CCP. > > CCP needs some TLC and I'm going to apply that during stage1.
With the propagator engine improvement this need some extra testcase adjustments. Re-bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Note that the "obvious" improvement of ccp_lattice_meet to if (val1->lattice_val == UNDEFINED /* For UNDEFINED M SSA we can't always SSA because its definition may not dominate the PHI node. */ && (val2->lattice_val != CONSTANT || TREE_CODE (val2->value) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (val2->value) || (gimple_bb (SSA_NAME_DEF_STMT (val2->value)) != where && dominated_by_p (CDI_DOMINATORS, where, gimple_bb (SSA_NAME_DEF_STMT (val2->value)))))) to enable optimistic copy propagation (yes, copyprop doesn't do that) regresses quite some gcc.dg/uninit-pred*.c testcases, so I'm at least not enabling this with this patch. For example in gcc.dg/uninit-pred-2_a.c: int foo (int n, int m, int r) { int flag = 0; int v; if (n) { v = r; flag = 1; } if (m) g++; else bar(); /* Wrong guard */ if (!flag) blah(v); /* { dg-warning "uninitialized" "real uninitialized var warning" } */ we see that we can optimistically propagate r into v for the call due to the PHI v_3 = PHI <v_1(D)(2), v_2(3)> and v being uninitialized on one path. We have similar missed uninit warnings for optimistic constant propagations already so I think optimistically propagating copies isn't wrong. We might want to provide a flag to turn both off, of course. I'll send a followup enabling optimistic copyprop once I get my mind around on how to fix the testcases. Richard. 2015-04-16 Richard Biener <rguent...@suse.de> PR tree-optimization/65650 * tree-ssa-ccp.c (valid_lattice_transition): Allow lattice transitions involving copies. (set_lattice_value): Adjust for copy lattice state. (ccp_lattice_meet): Do not merge UNDEFINED and a copy to the copy if that doesn't dominate the merge point. (bit_value_unop): Adjust what we treat as varying mask. (bit_value_binop): Likewise. (bit_value_assume_aligned): Likewise. (evaluate_stmt): When we simplified to a SSA name record a copy instead of dropping to varying. (visit_assignment): Simplify. * gimple-match.h (gimple_simplify): Add another callback. * gimple-fold.c (fold_stmt_1): Adjust caller. (gimple_fold_stmt_to_constant_1): Likewise - pass valueize for the 2nd callback. * gimple-match-head.c (gimple_simplify): Add a callback that is used to valueize the stmt operands and use it that way. * gcc.dg/tree-ssa/ssa-ccp-37.c: New testcase. * gcc.dg/tree-ssa/forwprop-11.c: Adjust. * gcc.dg/tree-ssa/ssa-fre-3.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-4.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-5.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-32.c: Likewise. Index: gcc/gimple-fold.c =================================================================== *** gcc/gimple-fold.c (revision 222266) --- gcc/gimple-fold.c (working copy) *************** fold_stmt_1 (gimple_stmt_iterator *gsi, *** 3621,3627 **** gimple_seq seq = NULL; code_helper rcode; tree ops[3] = {}; ! if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize)) { if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace)) changed = true; --- 3621,3628 ---- gimple_seq seq = NULL; code_helper rcode; tree ops[3] = {}; ! if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, ! valueize, valueize)) { if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace)) changed = true; *************** gimple_fold_stmt_to_constant_1 (gimple s *** 4928,4934 **** edges if there are intermediate VARYING defs. For this reason do not follow SSA edges here even though SCCVN can technically just deal fine with that. */ ! if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize) && rcode.is_tree_code () && (TREE_CODE_LENGTH ((tree_code) rcode) == 0 || ((tree_code) rcode) == ADDR_EXPR) --- 4929,4935 ---- edges if there are intermediate VARYING defs. For this reason do not follow SSA edges here even though SCCVN can technically just deal fine with that. */ ! if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize) && rcode.is_tree_code () && (TREE_CODE_LENGTH ((tree_code) rcode) == 0 || ((tree_code) rcode) == ADDR_EXPR) Index: gcc/gimple-match-head.c =================================================================== *** gcc/gimple-match-head.c (revision 222266) --- gcc/gimple-match-head.c (working copy) *************** gimple_simplify (enum built_in_function *** 601,607 **** bool gimple_simplify (gimple stmt, code_helper *rcode, tree *ops, ! gimple_seq *seq, tree (*valueize)(tree)) { switch (gimple_code (stmt)) { --- 601,608 ---- bool gimple_simplify (gimple stmt, code_helper *rcode, tree *ops, ! gimple_seq *seq, ! tree (*valueize)(tree), tree (*top_valueize)(tree)) { switch (gimple_code (stmt)) { *************** gimple_simplify (gimple stmt, *** 617,625 **** || code == VIEW_CONVERT_EXPR) { tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); ! if (valueize && TREE_CODE (op0) == SSA_NAME) { ! tree tem = valueize (op0); if (tem) op0 = tem; } --- 618,626 ---- || code == VIEW_CONVERT_EXPR) { tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); ! if (top_valueize && TREE_CODE (op0) == SSA_NAME) { ! tree tem = top_valueize (op0); if (tem) op0 = tem; } *************** gimple_simplify (gimple stmt, *** 631,639 **** { tree rhs1 = gimple_assign_rhs1 (stmt); tree op0 = TREE_OPERAND (rhs1, 0); ! if (valueize && TREE_CODE (op0) == SSA_NAME) { ! tree tem = valueize (op0); if (tem) op0 = tem; } --- 632,640 ---- { tree rhs1 = gimple_assign_rhs1 (stmt); tree op0 = TREE_OPERAND (rhs1, 0); ! if (top_valueize && TREE_CODE (op0) == SSA_NAME) { ! tree tem = top_valueize (op0); if (tem) op0 = tem; } *************** gimple_simplify (gimple stmt, *** 644,653 **** return gimple_resimplify3 (seq, rcode, type, ops, valueize); } else if (code == SSA_NAME ! && valueize) { tree op0 = gimple_assign_rhs1 (stmt); ! tree valueized = valueize (op0); if (!valueized || op0 == valueized) return false; ops[0] = valueized; --- 645,654 ---- return gimple_resimplify3 (seq, rcode, type, ops, valueize); } else if (code == SSA_NAME ! && top_valueize) { tree op0 = gimple_assign_rhs1 (stmt); ! tree valueized = top_valueize (op0); if (!valueized || op0 == valueized) return false; ops[0] = valueized; *************** gimple_simplify (gimple stmt, *** 658,666 **** case GIMPLE_UNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = valueize (rhs1); if (tem) rhs1 = tem; } --- 659,667 ---- case GIMPLE_UNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } *************** gimple_simplify (gimple stmt, *** 671,686 **** case GIMPLE_BINARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); ! if (valueize && TREE_CODE (rhs2) == SSA_NAME) { ! tree tem = valueize (rhs2); if (tem) rhs2 = tem; } --- 672,687 ---- case GIMPLE_BINARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); ! if (top_valueize && TREE_CODE (rhs2) == SSA_NAME) { ! tree tem = top_valueize (rhs2); if (tem) rhs2 = tem; } *************** gimple_simplify (gimple stmt, *** 692,714 **** case GIMPLE_TERNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); ! if (valueize && TREE_CODE (rhs2) == SSA_NAME) { ! tree tem = valueize (rhs2); if (tem) rhs2 = tem; } tree rhs3 = gimple_assign_rhs3 (stmt); ! if (valueize && TREE_CODE (rhs3) == SSA_NAME) { ! tree tem = valueize (rhs3); if (tem) rhs3 = tem; } --- 693,715 ---- case GIMPLE_TERNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); ! if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { ! tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); ! if (top_valueize && TREE_CODE (rhs2) == SSA_NAME) { ! tree tem = top_valueize (rhs2); if (tem) rhs2 = tem; } tree rhs3 = gimple_assign_rhs3 (stmt); ! if (top_valueize && TREE_CODE (rhs3) == SSA_NAME) { ! tree tem = top_valueize (rhs3); if (tem) rhs3 = tem; } *************** gimple_simplify (gimple stmt, *** 732,740 **** /* ??? Internal function support missing. */ if (!fn) return false; ! if (valueize && TREE_CODE (fn) == SSA_NAME) { ! tree tem = valueize (fn); if (tem) fn = tem; } --- 733,741 ---- /* ??? Internal function support missing. */ if (!fn) return false; ! if (top_valueize && TREE_CODE (fn) == SSA_NAME) { ! tree tem = top_valueize (fn); if (tem) fn = tem; } *************** gimple_simplify (gimple stmt, *** 754,762 **** case 1: { tree arg1 = gimple_call_arg (stmt, 0); ! if (valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = valueize (arg1); if (tem) arg1 = tem; } --- 755,763 ---- case 1: { tree arg1 = gimple_call_arg (stmt, 0); ! if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = top_valueize (arg1); if (tem) arg1 = tem; } *************** gimple_simplify (gimple stmt, *** 767,782 **** case 2: { tree arg1 = gimple_call_arg (stmt, 0); ! if (valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); ! if (valueize && TREE_CODE (arg2) == SSA_NAME) { ! tree tem = valueize (arg2); if (tem) arg2 = tem; } --- 768,783 ---- case 2: { tree arg1 = gimple_call_arg (stmt, 0); ! if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = top_valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); ! if (top_valueize && TREE_CODE (arg2) == SSA_NAME) { ! tree tem = top_valueize (arg2); if (tem) arg2 = tem; } *************** gimple_simplify (gimple stmt, *** 788,810 **** case 3: { tree arg1 = gimple_call_arg (stmt, 0); ! if (valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); ! if (valueize && TREE_CODE (arg2) == SSA_NAME) { ! tree tem = valueize (arg2); if (tem) arg2 = tem; } tree arg3 = gimple_call_arg (stmt, 2); ! if (valueize && TREE_CODE (arg3) == SSA_NAME) { ! tree tem = valueize (arg3); if (tem) arg3 = tem; } --- 789,811 ---- case 3: { tree arg1 = gimple_call_arg (stmt, 0); ! if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { ! tree tem = top_valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); ! if (top_valueize && TREE_CODE (arg2) == SSA_NAME) { ! tree tem = top_valueize (arg2); if (tem) arg2 = tem; } tree arg3 = gimple_call_arg (stmt, 2); ! if (top_valueize && TREE_CODE (arg3) == SSA_NAME) { ! tree tem = top_valueize (arg3); if (tem) arg3 = tem; } *************** gimple_simplify (gimple stmt, *** 823,838 **** case GIMPLE_COND: { tree lhs = gimple_cond_lhs (stmt); ! if (valueize && TREE_CODE (lhs) == SSA_NAME) { ! tree tem = valueize (lhs); if (tem) lhs = tem; } tree rhs = gimple_cond_rhs (stmt); ! if (valueize && TREE_CODE (rhs) == SSA_NAME) { ! tree tem = valueize (rhs); if (tem) rhs = tem; } --- 824,839 ---- case GIMPLE_COND: { tree lhs = gimple_cond_lhs (stmt); ! if (top_valueize && TREE_CODE (lhs) == SSA_NAME) { ! tree tem = top_valueize (lhs); if (tem) lhs = tem; } tree rhs = gimple_cond_rhs (stmt); ! if (top_valueize && TREE_CODE (rhs) == SSA_NAME) { ! tree tem = top_valueize (rhs); if (tem) rhs = tem; } Index: gcc/gimple-match.h =================================================================== *** gcc/gimple-match.h (revision 222266) --- gcc/gimple-match.h (working copy) *************** private: *** 41,47 **** }; bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *, ! tree (*)(tree)); tree maybe_push_res_to_seq (code_helper, tree, tree *, gimple_seq *, tree res = NULL_TREE); void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree); --- 41,47 ---- }; bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *, ! tree (*)(tree), tree (*)(tree)); tree maybe_push_res_to_seq (code_helper, tree, tree *, gimple_seq *, tree res = NULL_TREE); void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree); Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c (revision 222266) --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c (working copy) *************** int g(int *p, int n) *** 16,20 **** return q[-1]; } ! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_.. \\\+ 4B\\\];" 2 "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ --- 16,20 ---- return q[-1]; } ! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_\[0-9\]+(?:\\(D\\))? \\\+ 4B\\\];" 2 "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-ccp1" } */ + + int foo (int i) + { + int j = i; + int k = 0; + int l = j + k; + int m = l - j; + return m; + } + + /* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */ + /* { dg-final { cleanup-tree-dump "ccp1" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c (revision 222266) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c (working copy) *************** *** 6,12 **** When the condition is true, we distribute "(int) (a + b)" as "(int) a + (int) b", otherwise we keep the original. */ /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */ ! /* { dg-options "-O -fno-tree-forwprop -fwrapv -fdump-tree-fre1-details" } */ /* From PR14844. */ --- 6,12 ---- When the condition is true, we distribute "(int) (a + b)" as "(int) a + (int) b", otherwise we keep the original. */ /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */ ! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv -fdump-tree-fre1-details" } */ /* From PR14844. */ Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c (revision 222266) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c (working copy) *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ _Complex float m; --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fdump-tree-fre1-details" } */ _Complex float m; Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c (revision 222266) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c (working copy) *************** *** 1,7 **** /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there will be no casts for FRE to eliminate and the test will fail. */ /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* } } */ ! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR21608. */ --- 1,7 ---- /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there will be no casts for FRE to eliminate and the test will fail. */ /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* } } */ ! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR21608. */ Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c (revision 222266) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c (working copy) *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR19792. */ --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR19792. */ Index: gcc/tree-ssa-ccp.c =================================================================== *** gcc/tree-ssa-ccp.c (revision 222266) --- gcc/tree-ssa-ccp.c (working copy) *************** valid_lattice_transition (ccp_prop_value *** 439,444 **** --- 439,455 ---- /* Now both lattice values are CONSTANT. */ + /* Allow arbitrary copy changes as we might look through PHI <a_1, ...> + when only a single copy edge is executable. */ + if (TREE_CODE (old_val.value) == SSA_NAME + && TREE_CODE (new_val.value) == SSA_NAME) + return true; + + /* Allow transitioning from a constant to a copy. */ + if (is_gimple_min_invariant (old_val.value) + && TREE_CODE (new_val.value) == SSA_NAME) + return true; + /* Allow transitioning from PHI <&x, not executable> == &x to PHI <&x, &y> == common alignment. */ if (TREE_CODE (old_val.value) != INTEGER_CST *************** set_lattice_value (tree var, ccp_prop_va *** 527,535 **** caller that this was a non-transition. */ if (old_val->lattice_val != new_val.lattice_val || (new_val.lattice_val == CONSTANT ! && TREE_CODE (new_val.value) == INTEGER_CST ! && (TREE_CODE (old_val->value) != INTEGER_CST ! || new_val.mask != old_val->mask))) { /* ??? We would like to delay creation of INTEGER_CSTs from partially constants here. */ --- 538,547 ---- caller that this was a non-transition. */ if (old_val->lattice_val != new_val.lattice_val || (new_val.lattice_val == CONSTANT ! && (TREE_CODE (new_val.value) != TREE_CODE (old_val->value) ! || simple_cst_equal (new_val.value, old_val->value) != 1 ! || (TREE_CODE (new_val.value) == INTEGER_CST ! && new_val.mask != old_val->mask)))) { /* ??? We would like to delay creation of INTEGER_CSTs from partially constants here. */ *************** ccp_finalize (void) *** 965,978 **** */ static void ! ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2) { ! if (val1->lattice_val == UNDEFINED) { /* UNDEFINED M any = any */ *val1 = *val2; } ! else if (val2->lattice_val == UNDEFINED) { /* any M UNDEFINED = any Nothing to do. VAL1 already contains the value we want. */ --- 977,999 ---- */ static void ! ccp_lattice_meet (basic_block where, ! ccp_prop_value_t *val1, ccp_prop_value_t *val2) { ! if (val1->lattice_val == UNDEFINED ! /* For UNDEFINED M SSA we can't always SSA because its definition ! may not dominate the PHI node. Doing optimistic copy propagation ! also causes a lot of gcc.dg/uninit-pred*.c FAILs. */ ! && (val2->lattice_val != CONSTANT ! || TREE_CODE (val2->value) != SSA_NAME)) { /* UNDEFINED M any = any */ *val1 = *val2; } ! else if (val2->lattice_val == UNDEFINED ! /* See above. */ ! && (val1->lattice_val != CONSTANT ! || TREE_CODE (val1->value) != SSA_NAME)) { /* any M UNDEFINED = any Nothing to do. VAL1 already contains the value we want. */ *************** ccp_lattice_meet (ccp_prop_value_t *val1 *** 1026,1032 **** *val1 = get_value_for_expr (val1->value, true); if (TREE_CODE (val2->value) == ADDR_EXPR) tem = get_value_for_expr (val2->value, true); ! ccp_lattice_meet (val1, &tem); } else { --- 1047,1053 ---- *val1 = get_value_for_expr (val1->value, true); if (TREE_CODE (val2->value) == ADDR_EXPR) tem = get_value_for_expr (val2->value, true); ! ccp_lattice_meet (where, val1, &tem); } else { *************** ccp_visit_phi_node (gphi *phi) *** 1095,1101 **** tree arg = gimple_phi_arg (phi, i)->def; ccp_prop_value_t arg_val = get_value_for_expr (arg, false); ! ccp_lattice_meet (&new_val, &arg_val); if (dump_file && (dump_flags & TDF_DETAILS)) { --- 1116,1122 ---- tree arg = gimple_phi_arg (phi, i)->def; ccp_prop_value_t arg_val = get_value_for_expr (arg, false); ! ccp_lattice_meet (gimple_bb (phi), &new_val, &arg_val); if (dump_file && (dump_flags & TDF_DETAILS)) { *************** evaluate_stmt (gimple stmt) *** 1929,1937 **** /* The statement produced a nonconstant value. */ if (!is_constant) { ! val.lattice_val = VARYING; ! val.mask = -1; ! val.value = NULL_TREE; } return val; --- 1950,1970 ---- /* The statement produced a nonconstant value. */ if (!is_constant) { ! /* The statement produced a copy. */ ! if (simplified && TREE_CODE (simplified) == SSA_NAME ! && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified)) ! { ! val.lattice_val = CONSTANT; ! val.value = simplified; ! val.mask = -1; ! } ! /* The statement is VARYING. */ ! else ! { ! val.lattice_val = VARYING; ! val.value = NULL_TREE; ! val.mask = -1; ! } } return val; *************** static enum ssa_prop_result *** 2243,2269 **** visit_assignment (gimple stmt, tree *output_p) { ccp_prop_value_t val; ! enum ssa_prop_result retval; tree lhs = gimple_get_lhs (stmt); - - gcc_assert (gimple_code (stmt) != GIMPLE_CALL - || gimple_call_lhs (stmt) != NULL_TREE); - - if (gimple_assign_single_p (stmt) - && gimple_assign_rhs_code (stmt) == SSA_NAME) - /* For a simple copy operation, we copy the lattice values. */ - val = *get_value (gimple_assign_rhs1 (stmt)); - else - /* Evaluate the statement, which could be - either a GIMPLE_ASSIGN or a GIMPLE_CALL. */ - val = evaluate_stmt (stmt); - - retval = SSA_PROP_NOT_INTERESTING; - - /* Set the lattice value of the statement's output. */ if (TREE_CODE (lhs) == SSA_NAME) { /* If STMT is an assignment to an SSA_NAME, we only have one value to set. */ if (set_lattice_value (lhs, val)) --- 2276,2290 ---- visit_assignment (gimple stmt, tree *output_p) { ccp_prop_value_t val; ! enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING; tree lhs = gimple_get_lhs (stmt); if (TREE_CODE (lhs) == SSA_NAME) { + /* Evaluate the statement, which could be + either a GIMPLE_ASSIGN or a GIMPLE_CALL. */ + val = evaluate_stmt (stmt); + /* If STMT is an assignment to an SSA_NAME, we only have one value to set. */ if (set_lattice_value (lhs, val))