1 /* PR66119 - MOVE_RATIO is not constant in a compiler run, so Scalar
2    Reduction of Aggregates must ask the back-end more than once what
3    the value of MOVE_RATIO now is.  */
4 
5 /* { dg-do compile  { target { { i?86-*-* x86_64-*-* } && c++11 } }  }  */
6 /* { dg-options "-O3 -mavx -fdump-tree-sra -march=slm -mtune=slm" } */
7 
8 #include <immintrin.h>
9 
10 class MyAVX
11 {
12   __m256d data;
13 public:
14   MyAVX () = default;
15   MyAVX (const MyAVX &) = default;
MyAVX(__m256d _data)16   MyAVX (__m256d _data) : data(_data) { ; }
17 
18   MyAVX & operator= (const MyAVX &) = default;
19 
__m256d()20   operator __m256d () const { return data; }
21   MyAVX operator+ (MyAVX s2) { return data+s2.data; }
22 };
23 
24 template <typename T> class AVX_trait { ; };
25 
26 template <> class AVX_trait<double> {
27 public:
28   typedef __m256d TSIMD;
29 };
30 
31 
32 template <typename T>
33 class MyTSIMD
34 {
35   typename AVX_trait<T>::TSIMD data;
36 
37 public:
38   MyTSIMD () = default;
39   MyTSIMD (const MyTSIMD &) = default;
40   // MyTSIMD (const MyTSIMD & s2) : data(s2.data) { ; }
MyTSIMD(typename AVX_trait<T>::TSIMD _data)41   MyTSIMD (typename AVX_trait<T>::TSIMD _data) : data(_data) { ; }
42 
TSIMD()43   operator typename AVX_trait<T>::TSIMD() const { return data; }
44   MyTSIMD operator+ (MyTSIMD s2) { return data+s2.data; }
45 };
46 
47 // using MyVec = MyAVX;
48 using MyVec = MyTSIMD<double>;
49 
50 class Vec2
51 {
52   MyVec a, b;
53 public:
Vec2(MyVec aa,MyVec ab)54   Vec2 (MyVec aa, MyVec ab) : a(aa), b(ab) { ; }
55   Vec2 operator+ (Vec2 v2) { return Vec2(a+v2.a, b+v2.b); }
56 };
57 
58 inline __attribute__ ((__always_inline__))
ComputeSomething(Vec2 a,Vec2 b)59 Vec2 ComputeSomething (Vec2 a, Vec2 b)
60 {
61   return a+b;
62 }
63 
TestFunction(Vec2 a,Vec2 b)64 Vec2 TestFunction (Vec2 a, Vec2 b)
65 {
66   return ComputeSomething (a,b);
67 }
68 
69 /* { dg-final { scan-tree-dump "Created a replacement for b" "sra" } } */
70