| /* { 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" } } */ |