re PR tree-optimization/91597 (GCC miscompiles a branch depending on a pointer tag)
PR tree-optimization/91597 * tree-vrp.c (extract_range_from_binary_expr): Remove unsafe BIT_AND_EXPR optimization for pointers, even if both operand ranges don't include NULL, the result can be NULL. * gcc.c-torture/execute/pr91597.c: New test. Co-Authored-By: Richard Biener <rguenther@suse.de> From-SVN: r275330
This commit is contained in:
parent
e4a8d4a7ec
commit
3729852e40
4 changed files with 63 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
|||
2019-09-03 Jakub Jelinek <jakub@redhat.com>
|
||||
Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/91597
|
||||
* tree-vrp.c (extract_range_from_binary_expr): Remove unsafe
|
||||
BIT_AND_EXPR optimization for pointers, even if both operand
|
||||
ranges don't include NULL, the result can be NULL.
|
||||
|
||||
2019-09-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR middle-end/91605
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2019-09-03 Jakub Jelinek <jakub@redhat.com>
|
||||
Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/91597
|
||||
* gcc.c-torture/execute/pr91597.c: New test.
|
||||
|
||||
2019-09-03 Alexandre Oliva <oliva@adacore.com>
|
||||
|
||||
* gcc.target/i386/20020616-1.c: Preserve full register across
|
||||
|
|
48
gcc/testsuite/gcc.c-torture/execute/pr91597.c
Normal file
48
gcc/testsuite/gcc.c-torture/execute/pr91597.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* PR tree-optimization/91597 */
|
||||
|
||||
enum E { A, B, C };
|
||||
struct __attribute__((aligned (4))) S { enum E e; };
|
||||
|
||||
enum E
|
||||
foo (struct S *o)
|
||||
{
|
||||
if (((__UINTPTR_TYPE__) (o) & 1) == 0)
|
||||
return o->e;
|
||||
else
|
||||
return A;
|
||||
}
|
||||
|
||||
int
|
||||
bar (struct S *o)
|
||||
{
|
||||
return foo (o) == B || foo (o) == C;
|
||||
}
|
||||
|
||||
static inline void
|
||||
baz (struct S *o, int d)
|
||||
{
|
||||
if (__builtin_expect (!bar (o), 0))
|
||||
__builtin_abort ();
|
||||
if (d > 2) return;
|
||||
baz (o, d + 1);
|
||||
}
|
||||
|
||||
void
|
||||
qux (struct S *o)
|
||||
{
|
||||
switch (o->e)
|
||||
{
|
||||
case A: return;
|
||||
case B: baz (o, 0); break;
|
||||
case C: baz (o, 0); break;
|
||||
}
|
||||
}
|
||||
|
||||
struct S s = { C };
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
qux (&s);
|
||||
return 0;
|
||||
}
|
|
@ -1741,9 +1741,7 @@ extract_range_from_binary_expr (value_range_base *vr,
|
|||
{
|
||||
/* For pointer types, we are really only interested in asserting
|
||||
whether the expression evaluates to non-NULL. */
|
||||
if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1))
|
||||
vr->set_nonzero (expr_type);
|
||||
else if (vr0.zero_p () || vr1.zero_p ())
|
||||
if (vr0.zero_p () || vr1.zero_p ())
|
||||
vr->set_zero (expr_type);
|
||||
else
|
||||
vr->set_varying (expr_type);
|
||||
|
|
Loading…
Add table
Reference in a new issue