Bug 19659 - GCC does not remove an "if" statement that never triggers.
Summary: GCC does not remove an "if" statement that never triggers.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: unknown
: P2 enhancement
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, TREE
Depends on: 18178
Blocks: 19721
  Show dependency treegraph
 
Reported: 2005-01-27 19:59 UTC by Kazu Hirata
Modified: 2005-04-13 18:10 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-01-27 20:23:21


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kazu Hirata 2005-01-27 19:59:23 UTC
extern void abort (void) __attribute__ ((__noreturn__));

/* Count up to *LENGTHP and then return 0.  */

int
foo (unsigned *lengthp)
{
  unsigned index;

  for (index = 0; index != *lengthp; index++)
    {
      const unsigned *lengthp2 = lengthp;

      /* Note that this condition is never true.  */
      if (index >= *lengthp2)
	abort ();
    }

  return 0;
}

GCC does not remove the "if" statement even though it never triggers.

Interestingly, if you remove "const" from the testcase above, GCC does
remove the "if" statement.

If you feed the testcase with "const" into GCC, CSE removes it.
Hey, but isn't this a machine-independent optimization?
Comment 1 Andrew Pinski 2005-01-27 20:29:54 UTC
This is related to PR 18178 (which is the java equivant) by the way.
Comment 2 Steven Bosscher 2005-01-27 21:26:24 UTC
The lang hook thinks that with the 'const' the types of 'dest' and 'orig' 
in may_propagate_copy are not the same. 
 
(gdb) 
2820          else if (!may_propagate_copy (op, val)) 
4: debug_generic_stmt (stmt) = #   VUSE <TMT.0D.1464_10>; 
D.1457_8 = *lengthp2D.1453_7; 
 
void 
(gdb) p may_propagate_copy (op, val) 
$17 = 0 '\0' 
 
In may_propagate_copy : 
(gdb) next 
111           if (mt_dest && mt_orig && mt_dest != mt_orig) 
(gdb) 
113           else if (!lang_hooks.types_compatible_p (type_d, type_o)) 
(gdb) 
156     } 
(gdb) p debug_generic_expr(dest) 
lengthp2D.1453_7 
$18 = void 
(gdb) p debug_generic_expr(orig) 
lengthpD.1449_3 
(gdb) p lang_hooks.types_compatible_p (type_d, type_o) 
$20 = 0 
(gdb) p debug_tree (type_d) 
 <pointer_type 0x2a95a301a0 
    type <integer_type 0x2a95a300d0 unsigned int readonly unsigned SI 
        size <integer_cst 0x2a95890a80 constant invariant 32> 
        unit size <integer_cst 0x2a958905a0 constant invariant 4> 
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst 
0x2a95890b70 0> max <integer_cst 0x2a95890b40 4294967295> 
        pointer_to_this <pointer_type 0x2a95a301a0>> 
    unsigned DI 
    size <integer_cst 0x2a95890c30 type <integer_type 0x2a958965b0 
bit_size_type> constant invariant 64> 
    unit size <integer_cst 0x2a95890c60 type <integer_type 0x2a958964e0 long 
unsigned int> constant invariant 8> 
    align 64 symtab 0 alias set -1> 
$21 = void 
(gdb) p debug_tree (type_o) 
 <pointer_type 0x2a95988a90 
    type <integer_type 0x2a95896b60 unsigned int public unsigned SI 
        size <integer_cst 0x2a95890a80 constant invariant 32> 
        unit size <integer_cst 0x2a958905a0 constant invariant 4> 
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst 
0x2a95890b70 0> max <integer_cst 0x2a95890b40 4294967295> 
        pointer_to_this <pointer_type 0x2a95988a90>> 
    unsigned DI 
    size <integer_cst 0x2a95890c30 type <integer_type 0x2a958965b0 
bit_size_type> constant invariant 64> 
    unit size <integer_cst 0x2a95890c60 type <integer_type 0x2a958964e0 long 
unsigned int> constant invariant 8> 
    align 64 symtab 0 alias set -1> 
$22 = void 
 
 
 
Comment 3 Andrew Pinski 2005-02-17 04:12:21 UTC
This is not fully related to PR 18178 but this case is just a missed optimization dealing with const int * 
vs int*.

Another testcase for the const* vs * is:
void link_error(void);
void f(void)
{
  int a[1];
  a[0] = 1;
  const int *b = a;
  if (*b != 1)
    link_error();
}

If we look at the last tree dump we see there is a link_error in it.
Comment 4 Steven Bosscher 2005-03-16 12:32:34 UTC
Diego, this happens *a lot* in GCC itself.  All suggestions
on how we can fix this problem are welcome... ;-)
Comment 5 Andrew Pinski 2005-03-23 19:59:40 UTC
Hmm, the example in comment #3 is fixed on the mainline but the orginal one is just as bad when 
removing const now.
Comment 6 Andrew Pinski 2005-04-13 18:10:53 UTC
Fixed.