This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR35869, bad interaction with SSA updating and switch stmt optimization
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 11 Apr 2008 16:12:46 +0200 (CEST)
- Subject: [PATCH] Fix PR35869, bad interaction with SSA updating and switch stmt optimization
This fixes the bug by scheduling the switch stmt optimization after the
SSA update required before jump threading. It also "disables" the
optimization doing only one cfg_cleanup run and schedules a second one
after the switch stmt update.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2008-04-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35869
* tree-vrp.c (execute_vrp): Move switch statement update after
jump threading. Schedule another cfg cleanup run.
* gcc.c-torture/compile/pr35869.c: New testcase.
Index: tree-vrp.c
===================================================================
*** tree-vrp.c (revision 134193)
--- tree-vrp.c (working copy)
*************** execute_vrp (void)
*** 6734,6753 ****
ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
vrp_finalize ();
- /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
- CFG in a broken state and requires a cfg_cleanup run. */
- for (i = 0; VEC_iterate (edge, to_remove_edges, i, e); ++i)
- remove_edge (e);
- /* Update SWITCH_EXPR case label vector. */
- for (i = 0; VEC_iterate (switch_update, to_update_switch_stmts, i, su); ++i)
- SWITCH_LABELS (su->stmt) = su->vec;
-
- if (VEC_length (edge, to_remove_edges) > 0)
- free_dominance_info (CDI_DOMINATORS);
-
- VEC_free (edge, heap, to_remove_edges);
- VEC_free (switch_update, heap, to_update_switch_stmts);
-
/* ASSERT_EXPRs must be removed before finalizing jump threads
as finalizing jump threads calls the CFG cleanup code which
does not properly handle ASSERT_EXPRs. */
--- 6734,6739 ----
*************** execute_vrp (void)
*** 6761,6766 ****
--- 6747,6770 ----
update_ssa (TODO_update_ssa);
finalize_jump_threads ();
+
+ /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
+ CFG in a broken state and requires a cfg_cleanup run. */
+ for (i = 0; VEC_iterate (edge, to_remove_edges, i, e); ++i)
+ remove_edge (e);
+ /* Update SWITCH_EXPR case label vector. */
+ for (i = 0; VEC_iterate (switch_update, to_update_switch_stmts, i, su); ++i)
+ SWITCH_LABELS (su->stmt) = su->vec;
+
+ if (VEC_length (edge, to_remove_edges) > 0)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ cleanup_tree_cfg ();
+ }
+
+ VEC_free (edge, heap, to_remove_edges);
+ VEC_free (switch_update, heap, to_update_switch_stmts);
+
scev_finalize ();
loop_optimizer_finalize ();
Index: testsuite/gcc.c-torture/compile/pr35869.c
===================================================================
*** testsuite/gcc.c-torture/compile/pr35869.c (revision 0)
--- testsuite/gcc.c-torture/compile/pr35869.c (revision 0)
***************
*** 0 ****
--- 1,47 ----
+ struct texture_stage_op
+ {
+ unsigned int carg1, carg2, carg0;
+ unsigned int aarg1, aarg2, aarg0;
+ unsigned int dst;
+ };
+
+ static const char *debug_register(unsigned int reg) {
+ switch(reg) {
+ case 0x8921: return "GL_REG_0_ATI";
+ case 0x8923: return "GL_REG_2_ATI";
+ case 0x0: return "GL_ZERO";
+ case 0x1: return "GL_ONE";
+ default: return "Unknown register\n";
+ }
+ }
+
+ static unsigned int find_tmpreg(struct texture_stage_op op[8]) {
+ int i;
+ int tex_used[8];
+
+ for(i = 0; i < 8; i++) {
+ if(op[i].carg1 == 0x00000002 ) {
+ tex_used[i] = 1;
+ }
+ }
+
+ for(i = 1; i < 6; i++) {
+ if(!tex_used[i]) {
+ return 0x8921 + i;
+ }
+ }
+ return 0;
+ }
+
+ extern f(const char*);
+
+ void g() {
+ struct texture_stage_op op[8];
+ unsigned int tmparg = find_tmpreg(op);
+ unsigned int dstreg;
+
+ if(tmparg == 0x0) return;
+ dstreg = tmparg;
+ f(debug_register(dstreg));
+ return;
+ }