[Bug c/95448] New: Missing optimization: pointer untag, re-tag should be no-op
dancol at dancol dot org
gcc-bugzilla@gcc.gnu.org
Sun May 31 01:37:00 GMT 2020
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);
}
More information about the Gcc-bugs
mailing list