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).