https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79958

            Bug ID: 79958
           Summary: Missed tree DSE
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

At -O3 in bar we have various dead temporaries, they don't have address taken
and so should be DSEd, but they aren't.  In foo which doesn't have the EH edges
this works well.

#include <cstddef>
#include <functional>
#include <stdint.h>

namespace
{
  struct bitarray
  {
    bitarray(int i) : mSlice(i) {}
    template<typename EXPR>
    bitarray(const EXPR &expr) { mSlice = expr.slice(0); }
    uint32_t
    slice(ptrdiff_t index) const { if (index != 0) return 0; return mSlice; }
  private:
    uint32_t mSlice;
  };
  template<typename LEFT, typename RIGHT, template<typename T> class OP>
  struct bit_binary_expr
  {
    bit_binary_expr(const LEFT &left, const RIGHT &right) : mLeft(left),
mRight(right) {}
    uint32_t slice(ptrdiff_t index) const { OP<uint32_t> op; return
op(mLeft.slice(index), mRight.slice(index)); }
  private:
    const LEFT &mLeft;
    const RIGHT &mRight;
  };
  template<typename LEFT, typename RIGHT>
  bit_binary_expr<LEFT, RIGHT, ::std::bit_and>
  operator &(const LEFT &left, const RIGHT &right) { return
bit_binary_expr<LEFT, RIGHT, ::std::bit_and>(left, right); }
  template<typename LEFT, typename RIGHT>
  bit_binary_expr<LEFT, RIGHT, ::std::bit_or> operator |(const LEFT &left,
const RIGHT &right)
  { return bit_binary_expr<LEFT, RIGHT, ::std::bit_or>(left, right); }
  template<typename OPERAND>
  struct bit_shift_left
  {
    bit_shift_left(const OPERAND &operand, size_t nBits) : mOperand(operand),
mBits(nBits) {}
    uint32_t slice(ptrdiff_t index) const
    {
      const ptrdiff_t offset = mBits / 32;
      const size_t bits = mBits % 32;
      if (bits == 0)
        return mOperand.slice(index - offset);
      else
        return (mOperand.slice(index - offset) << bits) | (mOperand.slice(index
- offset - 1) >> (32 - bits));
    }
  private:
    const OPERAND &mOperand;
    const size_t mBits;
  };
  template<typename OPERAND>
  bit_shift_left<OPERAND> operator <<(const OPERAND &operand, size_t nBits) {
return bit_shift_left<OPERAND>(operand, nBits); }
}
struct Foo
{
  void write(const bitarray &);
};
void
foo(int i)
{
  Foo f;
  f.write(bitarray(( ((((bitarray(i)  & bitarray(0x00000001))) << 31) |
bitarray(0x40000000)))
            | ((((bitarray(42) & bitarray(0x0000ffff))) <<  8) |
bitarray(0x00000080))));
}
struct Bar
{
  ~Bar(void);
  void write(const bitarray &) /* throw() */;
};
void
bar(int i)
{
  Bar b;
  b.write(bitarray(( ((((bitarray(i)  & bitarray(0x00000001))) << 31) |
bitarray(0x40000000)))
            | ((((bitarray(42) & bitarray(0x0000ffff))) <<  8) |
bitarray(0x00000080))));
}

Reply via email to