Bug 30904 - VRP does not track values of shifts and/or bitfields?
Summary: VRP does not track values of shifts and/or bitfields?
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, TREE
Depends on:
Blocks: 31058
  Show dependency treegraph
 
Reported: 2007-02-21 09:53 UTC by Richard Biener
Modified: 2007-03-09 12:30 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-02-21 15:58:48


Attachments
patch to fix the bug (820 bytes, patch)
2007-02-21 16:23 UTC, Paolo Bonzini
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2007-02-21 09:53:50 UTC
extern void link_error (const char *);
extern int ones;
void foo(int);
void kernel ()
{
    struct { unsigned int a : 7; } s;

      s.a = ones;

      if (s.a >> 8)
          link_error ("foo");
      if (s.a >> 9)
          link_error ("foo");
}

mainline optimizes this to an empty function with -O2, dataflow branch
retains the s.a >> 9 check.
Comment 1 Serge Belyshev 2007-02-21 13:30:59 UTC
Confirmed, same problem on alphaev56-unknown-linux-gnu.
Comment 2 Steven Bosscher 2007-02-21 15:58:48 UTC
Problem here is combine.
Comment 3 Paolo Bonzini 2007-02-21 16:03:03 UTC
This unrelated patch fixes a very similar case for powerpc

unpatched:
<       or r0,r3,r28
<       rlwinm r0,r0,0,0xff
<       cmpwi cr7,r0,0
<       beq- cr7,L4929

patched: (r3 and r28 are both extended from QImode)
>       or. r0,r3,r28
>       beq- cr0,L4929


With some luck, it does the same for this testcase too?  It would be nice to examine why though. :-)

Sorry for the lack of professionality exhibited in this comment...

Index: combine.c
===================================================================
--- combine.c   (revision 122195)
+++ combine.c   (working copy)
@@ -1016,6 +1016,7 @@ combine_instructions (rtx f, unsigned in
 #endif
   rtx links, nextlinks;
   rtx first;
+  basic_block prev_basic_block;
 
   int new_direct_jump_p = 0;
 
@@ -1057,15 +1058,20 @@ combine_instructions (rtx f, unsigned in
      for what bits are known to be set.  */
 
   label_tick = label_tick_ebb_start = 1;
+  prev_basic_block = NULL;
 
   setup_incoming_promotions (first);
-
   create_log_links ();
+
   FOR_EACH_BB (this_basic_block)
     {
       last_call_luid = 0;
       mem_last_set = -1;
       label_tick++;
+      if (!single_pred_p (this_basic_block)
+         || single_pred (this_basic_block) != prev_basic_block)
+       label_tick_ebb_start = label_tick;
+
       FOR_BB_INSNS (this_basic_block, insn)
         if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
          {
@@ -1090,8 +1096,8 @@ combine_instructions (rtx f, unsigned in
              fprintf(dump_file, "insn_cost %d: %d\n",
                    INSN_UID (insn), INSN_COST (insn));
          }
-       else if (LABEL_P (insn))
-         label_tick_ebb_start = label_tick;
+
+      prev_basic_block = this_basic_block;
     }
 
   nonzero_sign_valid = 1;
@@ -1099,6 +1105,8 @@ combine_instructions (rtx f, unsigned in
   /* Now scan all the insns in forward order.  */
 
   label_tick = label_tick_ebb_start = 1;
+  prev_basic_block = NULL;
+
   init_reg_last ();
   setup_incoming_promotions (first);
 
@@ -1107,6 +1115,10 @@ combine_instructions (rtx f, unsigned in
       last_call_luid = 0;
       mem_last_set = -1;
       label_tick++;
+      if (!single_pred_p (this_basic_block)
+          || single_pred (this_basic_block) != prev_basic_block)
+        label_tick_ebb_start = label_tick;
+     
       for (insn = BB_HEAD (this_basic_block);
           insn != NEXT_INSN (BB_END (this_basic_block));
           insn = next ? next : NEXT_INSN (insn))
@@ -1253,9 +1265,9 @@ combine_instructions (rtx f, unsigned in
            retry:
              ;
            }
-         else if (LABEL_P (insn))
-           label_tick_ebb_start = label_tick;
        }
+
+      prev_basic_block = this_basic_block;
     }
 
   clear_log_links ();
Comment 4 Paolo Bonzini 2007-02-21 16:05:37 UTC
It doesn't, but I confirm that the bug is target independent.  A way to fix it would be to do the transform in VRP, but I'll look at combine if time permits.
Comment 5 Paolo Bonzini 2007-02-21 16:11:43 UTC
The first one is in the same EBB as the assignment.  The second one isn't and combine screws up.  This is because of the way combine treats regs with one def that dominates all uses, I talked to zadeck yesterday about that on IRC.
Comment 6 Paolo Bonzini 2007-02-21 16:23:57 UTC
Created attachment 13083 [details]
patch to fix the bug

The logic in trunk's combine with respect to uninitialized variables is correct.

We have to look at DF_LR_IN for the entry basic block to find variables that are not used uninitialized.

In fact, the name of DF_UR_IN is misleading, as it computes *initialized* registers.
Comment 7 Paolo Bonzini 2007-02-22 08:41:33 UTC
Now that the patch has been applied to dataflow branch, this remains as a missed optimization on the tree level.
Comment 8 Paolo Bonzini 2007-02-24 16:07:56 UTC
Subject: Bug 30904

Author: bonzini
Date: Sat Feb 24 16:07:41 2007
New Revision: 122290

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=122290
Log:
2007-02-23  Paolo Bonzini  <bonzini@gnu.org>

        PR tree-optimization/30904
	* gcc.dg/pr30904.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr30904.c
Modified:
    trunk/gcc/testsuite/ChangeLog

Comment 9 Richard Biener 2007-03-09 12:29:35 UTC
Subject: Bug 30904

Author: rguenth
Date: Fri Mar  9 12:29:09 2007
New Revision: 122748

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=122748
Log:
2007-03-09  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/30904
	PR middle-end/31058
	* tree-vrp.c (extract_range_from_binary_expr): Handle RSHIFT_EXPR
	the same way as *_DIV_EXPR.

	* gcc.dg/pr30904.c: Remove xfail.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/pr30904.c
    trunk/gcc/tree-vrp.c

Comment 10 Richard Biener 2007-03-09 12:29:41 UTC
Fixed.