This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]