blob: fafd3227181d37ae8c569cf1ab6e3897a3acd437 [file] [log] [blame]
/* { dg-do compile } */
/* { dg-require-effective-target c++17 } */
/* { dg-options "-O2 -fdump-tree-fre3" } */
struct _Base
{
int _M_data = 0;
};
struct _Wrapper : _Base
{
_Wrapper(int) {}
bool _M_is_constprop() { return __builtin_constant_p(_M_data); }
};
struct _Impl
{
_Wrapper _S_multiplies(_Wrapper __x, _Wrapper __y)
{
if (__x._M_is_constprop() || __y._M_is_constprop())
return __y;
return 0;
}
};
struct _TupleData
{
_Wrapper first;
int second;
};
struct _Tuple : _TupleData
{
template <typename _Fp>
_Tuple _M_apply_per_chunk(_Fp __fun, _Tuple __y)
{
return {__fun(first, __y.first), second};
}
};
struct _ImplFixed
{
static _Tuple _S_multiplies(_Tuple __x, _Tuple __y)
{
return __x._M_apply_per_chunk(
[]( auto __xx, auto __yy) {
return _Impl()._S_multiplies(__xx, __yy);
},
__y);
}
};
class simd
{
public:
[[__gnu__::__always_inline__]] friend simd operator*(simd __x, simd __y)
{ return _ImplFixed::_S_multiplies(__x._M_data, __y._M_data); }
simd(_Tuple __init) : _M_data(__init) {}
_Tuple _M_data;
};
int main()
{
simd({0, 0}) * simd({0, 0});
}
/* FRE3 should elide all conditionals in the remaining main. */
/* { dg-final { scan-tree-dump-times "<bb" 1 "fre3" } } */