public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op
@ 2020-05-31 1:37 dancol at dancol dot org
2020-06-02 8:09 ` [Bug tree-optimization/95448] " rguenth at gcc dot gnu.org
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: dancol at dancol dot org @ 2020-05-31 1:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95448
Bug ID: 95448
Summary: Missing optimization: pointer untag, re-tag should be
no-op
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: dancol at dancol dot org
Target Milestone: ---
Consider the following code. make_vector2() ought to be equivalent to just
"return make_vector_val()", and under Clang (10.0), it is. But GCC generates
this code for make_vector2:
make_vector2:
sub rsp, 8
call make_vector_val
add rsp, 8
and rax, -8
or rax, 1
ret
The assume() in the code ought to be sufficient for convincing GCC that it
doesn't need to munge the return value of make_vector_val(). Emacs uses
patterns like this one pretty frequently.
---
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define assume(x) do { if(!(x)) __builtin_unreachable(); } while(0)
enum { tagbits = 3 };
#define TAG_MASK (((uintptr_t)(1)<<tagbits) - 1)
#define TAG_VECTOR ((uintptr_t) 1)
typedef struct vector { double x; } vector;
typedef struct val {
uintptr_t v;
} val;
static inline void *PTR_OF(val v)
{
return (void *)(v.v & ~TAG_MASK);
}
static inline val TAG(void *v, uintptr_t tag)
{
uintptr_t l = (uintptr_t) v;
assume((l & TAG_MASK) == 0);
return (val){l | tag};
}
extern val make_vector_val(void);
val make_vector2(void)
{
val v = make_vector_val();
assume((v.v & TAG_MASK) == TAG_VECTOR);
struct vector *vs = PTR_OF(v);
return TAG(vs, TAG_VECTOR);
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/95448] Missing optimization: pointer untag, re-tag should be no-op
2020-05-31 1:37 [Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op dancol at dancol dot org
@ 2020-06-02 8:09 ` rguenth at gcc dot gnu.org
2021-11-22 10:36 ` pinskia at gcc dot gnu.org
2023-10-25 18:59 ` pinskia at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-06-02 8:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95448
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|middle-end |tree-optimization
Last reconfirmed| |2020-06-02
CC| |jakub at gcc dot gnu.org
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed. The pass with the strongest bit tracking (CCP) does not handle
the special assume-like CFGs at all and EVRP which would does not handle
the indirect assumption of bit test vs. constant:
_1 = v.v;
_2 = _1 & 7;
if (_2 != 1)
goto <bb 3>; [INV]
else
goto <bb 4>; [INV]
<bb 3> :
__builtin_unreachable ();
<bb 4> :
_12 = _1 & 18446744073709551608;
so while we see that _2 = [1, 1] at the start of bb 4 the value-range
for _1 is determined from
Adding assert for _1 from _1 + 18446744073709551615 <= 18446744073709551608
Adding assert for _1 from _1 != 0
to
pushing new range for _1: long unsigned int [1, 18446744073709551609]
EQUIVALENCES: { _1 } (1 elements)
sth is amiss there. It looks like is_masked_range_test is the closest
candidate but there
if ((inv_mask & (inv_mask + 1)) != 0
|| (val & mask) != val)
return false;
trips. Guess we're looking for a different kind of logic here.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/95448] Missing optimization: pointer untag, re-tag should be no-op
2020-05-31 1:37 [Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op dancol at dancol dot org
2020-06-02 8:09 ` [Bug tree-optimization/95448] " rguenth at gcc dot gnu.org
@ 2021-11-22 10:36 ` pinskia at gcc dot gnu.org
2023-10-25 18:59 ` pinskia at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-22 10:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95448
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Simplified testcase:
int f(int a)
{
if ((a&7) != 1) __builtin_unreachable();
a &= ~7;
a |= 1;
return a;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/95448] Missing optimization: pointer untag, re-tag should be no-op
2020-05-31 1:37 [Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op dancol at dancol dot org
2020-06-02 8:09 ` [Bug tree-optimization/95448] " rguenth at gcc dot gnu.org
2021-11-22 10:36 ` pinskia at gcc dot gnu.org
@ 2023-10-25 18:59 ` pinskia at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-10-25 18:59 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95448
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
ranger (EVRP) produces:
_1 = a_2(D) & 7;
if (_1 != 1)
goto <bb 3>; [INV]
else
goto <bb 4>; [INV]
_1 : [irange] int [0, 7] MASK 0x7 VALUE 0x0
2->3 (T) _1 : [irange] int [0, 0][2, 7] MASK 0x7 VALUE 0x0
2->4 (F) _1 : [irange] int [1, 1] MASK 0x7 VALUE 0x0
2->4 (F) a_2(D) : [irange] int [-INF, -7][1, +INF]
Notice how there is no mask/value info for a_2 here while there is for _1.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-10-25 18:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-31 1:37 [Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op dancol at dancol dot org
2020-06-02 8:09 ` [Bug tree-optimization/95448] " rguenth at gcc dot gnu.org
2021-11-22 10:36 ` pinskia at gcc dot gnu.org
2023-10-25 18:59 ` pinskia at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).