User account creation filtered due to spam.

Bug 47673

Summary: Redundant NULL check
Product: gcc Reporter: Ian Lance Taylor <ian>
Component: middle-endAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: adurbin
Priority: P3 Keywords: missed-optimization
Version: 4.6.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-02-10 00:06:01

Description Ian Lance Taylor 2011-02-09 23:44:41 UTC
Consider this C code:

struct s1 { int x; };
struct s2 { struct s1 *p1; };
extern void f1(struct s1 *);
static inline void inline_func(struct s1 *p1) { if (p1) f1 (p1); }
void global_function(struct s2 *p2) {
  if (p2->p1 != 0 && p2->p1 != (struct s1 *) -1)
    inline_func(p2->p1);
}

When I compile this with -O2 with current mainline on x86_64, I get this:

	movq	(%rdi), %rdi
	leaq	-1(%rdi), %rax
	cmpq	$-3, %rax
	ja	.L1
	testq	%rdi, %rdi
	je	.L1
	jmp	f1

If %rdi is 0, %rax will be -1, and the ja branch will be taken.  Therefore, the je following the testq %rdi,%rdi will never be taken.  The test and branch should be eliminated.
Comment 1 Andrew Pinski 2011-02-10 00:06:01 UTC
  if (p2->p1 + -1 <= -3B)

We should disable the optimization which converts 
p2->p1 != 0 && p2->p1 != (struct s1 *) -1 into p2->p1 + -1 <= -3B for pointer types.
Comment 2 Richard Biener 2011-02-10 00:22:05 UTC
(In reply to comment #1)
>   if (p2->p1 + -1 <= -3B)
> 
> We should disable the optimization which converts 
> p2->p1 != 0 && p2->p1 != (struct s1 *) -1 into p2->p1 + -1 <= -3B for pointer
> types.

No, VRP should simply work on pointers more properly.