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)))); }