Example: int f(int i) { int t = i == 1; int g = t == 2; int h = g == 3; return h; } We should convert this to return 0 on the tree level but currently we get: return i == 1 == 2 == 3; in final_cleanup
The fix would be instead of setting the range to varrying in extract_range_from_comparison, set it to [0,1].
I have a fix.
Created attachment 9610 [details] patch which I need to test This patch fixes the problem but exposes PR 23604 so I cannot bootstrap this test until PR 23604 is fixed as PR 23604 is exposed in compiling GCC.
This really does depend on PR 23604 as it exposes that latent bug while bootstrapping.
I just tried to bootstrap the patch on x86_64-linux-gnu and I think I ran into another VRP bug.
(In reply to comment #5) > I just tried to bootstrap the patch on x86_64-linux-gnu and I think I ran into > another VRP bug. I could not find it in cc1files and there was only one extra "Folding predicate" in the whole cc1files :(. I know it is in the gnat1 front-end but I really don't want to do the dumps for that :(.
(In reply to comment #6) > I know it is in the gnat1 front-end but I really don't want to do the dumps for > that :(. I figured out how to fix the problem but to me it seems like a front-end bug in that it does not set TREE_PRECISSION on its boolean type correctly.
The patch above is almost correct and I just lost the correct one as my laptop is dead so I am no longer working on this.
I am going to try to get this done for 4.3.0.
In extract_range_from_binary we have another case where we drop to varying: /* For integer ranges, apply the operation to each end of the range and see what we end up with. */ if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR || code == TRUTH_AND_EXPR || code == TRUTH_OR_EXPR) { ... else { set_value_range_to_varying (vr); return; } } But the latent problems seem to be fixed, the following (simple) patch bootstrapped and regtested ok for me: *************** extract_range_from_comparison (value_ran *** 1920,1926 **** set_value_range (vr, VR_RANGE, val, val, vr->equiv); } else ! set_value_range_to_varying (vr); } --- 1925,1933 ---- set_value_range (vr, VR_RANGE, val, val, vr->equiv); } else ! /* The result of a comparison is always true or false. */ ! set_value_range (vr, VR_RANGE, build_int_cst (TREE_TYPE (expr), 0), ! build_int_cst (TREE_TYPE (expr), 1), vr->equiv); }
Subject: Bug 23603 Author: rguenth Date: Mon Jan 8 11:20:00 2007 New Revision: 120578 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120578 Log: 2007-01-08 Richard Guenther <rguenther@suse.de> PR tree-optimization/23603 * tree-vrp.c (set_value_range_to_truthvalue): New function. (extract_range_from_binary): Fall back to truthvalue instead of varying for TRUTH_*_EXPR. (extract_range_from_comparison): Fall back to truthvalue instead of varying. (vrp_visit_phi_node): Don't adjust new range bounds to +INF/-INF if all visited PHI values were constant. * gcc.dg/tree-ssa/vrp31.c: New testcase. * gcc.dg/tree-ssa/vrp32.c: Likewise. Added: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp31.c trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp32.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-vrp.c
Fixed.