1 // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -Wno-unused -std=c++11 -emit-llvm -o - | FileCheck %s 2 3 using FourShorts = short __attribute__((__vector_size__(8))); 4 using TwoInts = int __attribute__((__vector_size__(8))); 5 using TwoUInts = unsigned __attribute__((__vector_size__(8))); 6 using FourInts = int __attribute__((__vector_size__(16))); 7 using FourUInts = unsigned __attribute__((__vector_size__(16))); 8 using TwoLongLong = long long __attribute__((__vector_size__(16))); 9 using FourLongLong = long long __attribute__((__vector_size__(32))); 10 using TwoFloats = float __attribute__((__vector_size__(8))); 11 using FourFloats = float __attribute__((__vector_size__(16))); 12 using TwoDoubles = double __attribute__((__vector_size__(16))); 13 using FourDoubles = double __attribute__((__vector_size__(32))); 14 15 FourShorts four_shorts; 16 TwoInts two_ints; 17 TwoUInts two_uints; 18 FourInts four_ints; 19 FourUInts four_uints; 20 TwoLongLong two_ll; 21 FourLongLong four_ll; 22 TwoFloats two_floats; 23 FourFloats four_floats; 24 TwoDoubles two_doubles; 25 FourDoubles four_doubles; 26 27 short some_short; 28 unsigned short some_ushort; 29 int some_int; 30 float some_float; 31 unsigned int some_uint; 32 long long some_ll; 33 unsigned long long some_ull; 34 double some_double; 35 36 // CHECK: TwoVectorOps 37 void TwoVectorOps() { 38 two_ints ? two_ints : two_ints; 39 // CHECK: %[[COND:.+]] = load <2 x i32> 40 // CHECK: %[[LHS:.+]] = load <2 x i32> 41 // CHECK: %[[RHS:.+]] = load <2 x i32> 42 // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i32> %[[COND]], zeroinitializer 43 // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x i32> %[[LHS]], <2 x i32> %[[RHS]] 44 45 two_ints ? two_floats : two_floats; 46 // CHECK: %[[COND:.+]] = load <2 x i32> 47 // CHECK: %[[LHS:.+]] = load <2 x float> 48 // CHECK: %[[RHS:.+]] = load <2 x float> 49 // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i32> %[[COND]], zeroinitializer 50 // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x float> %[[LHS]], <2 x float> %[[RHS]] 51 52 two_ll ? two_doubles : two_doubles; 53 // CHECK: %[[COND:.+]] = load <2 x i64> 54 // CHECK: %[[LHS:.+]] = load <2 x double> 55 // CHECK: %[[RHS:.+]] = load <2 x double> 56 // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i64> %[[COND]], zeroinitializer 57 // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x double> %[[LHS]], <2 x double> %[[RHS]] 58 } 59 60 // CHECK: TwoScalarOps 61 void TwoScalarOps() { 62 four_shorts ? some_short : some_short; 63 // CHECK: %[[COND:.+]] = load <4 x i16> 64 // CHECK: %[[LHS:.+]] = load i16 65 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[LHS]], i64 0 66 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i16> %[[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 67 // CHECK: %[[RHS:.+]] = load i16 68 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[RHS]], i64 0 69 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i16> %[[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 70 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i16> %[[COND]], zeroinitializer 71 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i16> %[[LHS_SPLAT]], <4 x i16> %[[RHS_SPLAT]] 72 73 four_shorts ? some_ushort : some_ushort; 74 // CHECK: %[[COND:.+]] = load <4 x i16> 75 // CHECK: %[[LHS:.+]] = load i16 76 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[LHS]], i64 0 77 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i16> %[[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 78 // CHECK: %[[RHS:.+]] = load i16 79 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[RHS]], i64 0 80 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i16> %[[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 81 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i16> %[[COND]], zeroinitializer 82 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i16> %[[LHS_SPLAT]], <4 x i16> %[[RHS_SPLAT]] 83 84 four_ints ? some_ushort : some_short; 85 // CHECK: %[[COND:.+]] = load <4 x i32> 86 // CHECK: %[[LHS:.+]] = load i16 87 // CHECK: %[[LHS_ZEXT:.+]] = zext i16 %[[LHS]] to i32 88 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS_ZEXT]], i64 0 89 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 90 // CHECK: %[[RHS:.+]] = load i16 91 // CHECK: %[[RHS_SEXT:.+]] = sext i16 %[[RHS]] to i32 92 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_SEXT]], i64 0 93 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 94 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 95 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS_SPLAT]] 96 97 four_ints ? some_int : some_float; 98 // CHECK: %[[COND:.+]] = load <4 x i32> 99 // CHECK: %[[LHS:.+]] = load i32 100 // CHECK: %[[LHS_CONV:.+]] = sitofp i32 %[[LHS]] to float 101 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[LHS_CONV]], i64 0 102 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x float> %[[LHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 103 // CHECK: %[[RHS:.+]] = load float 104 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[RHS]], i64 0 105 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x float> %[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 106 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 107 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x float> %[[LHS_SPLAT]], <4 x float> %[[RHS_SPLAT]] 108 109 four_ll ? some_double : some_ll; 110 // CHECK: %[[COND:.+]] = load <4 x i64> 111 // CHECK: %[[LHS:.+]] = load double 112 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x double> poison, double %[[LHS]], i64 0 113 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x double> %[[LHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer 114 // CHECK: %[[RHS:.+]] = load i64 115 // CHECK: %[[RHS_CONV:.+]] = sitofp i64 %[[RHS]] to double 116 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x double> poison, double %[[RHS_CONV]], i64 0 117 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x double> %[[RHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer 118 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 119 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x double> %[[LHS_SPLAT]], <4 x double> %[[RHS_SPLAT]] 120 121 four_ints ? some_int : some_short; 122 // CHECK: %[[COND:.+]] = load <4 x i32> 123 // CHECK: %[[LHS:.+]] = load i32 124 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS]], i64 0 125 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 126 // CHECK: %[[RHS:.+]] = load i16 127 // CHECK: %[[RHS_SEXT:.+]] = sext i16 %[[RHS]] to i32 128 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_SEXT]], i64 0 129 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 130 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 131 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS_SPLAT]] 132 } 133 134 // CHECK: OneScalarOp 135 void OneScalarOp() { 136 four_ints ? four_ints : some_int; 137 // CHECK: %[[COND:.+]] = load <4 x i32> 138 // CHECK: %[[LHS:.+]] = load <4 x i32> 139 // CHECK: %[[RHS:.+]] = load i32 140 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS]], i64 0 141 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 142 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 143 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> %[[RHS_SPLAT]] 144 145 four_ints ? four_ints : 5; 146 // CHECK: %[[COND:.+]] = load <4 x i32> 147 // CHECK: %[[LHS:.+]] = load <4 x i32> 148 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 149 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> splat (i32 5) 150 151 four_ints ?: some_float; 152 // CHECK: %[[COND:.+]] = load <4 x i32> 153 // CHECK: %[[RHS:.+]] = load float 154 // CHECK: %[[RHS_CONV:.+]] = fptosi float %[[RHS]] to i32 155 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_CONV]], i64 0 156 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 157 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 158 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[COND]], <4 x i32> %[[RHS_SPLAT]] 159 160 four_ints ? four_ints : 5.0f; 161 // CHECK: %[[COND:.+]] = load <4 x i32> 162 // CHECK: %[[LHS:.+]] = load <4 x i32> 163 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 164 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> splat (i32 5) 165 166 four_ints ? some_float : four_ints; 167 // CHECK: %[[COND:.+]] = load <4 x i32> 168 // CHECK: %[[LHS:.+]] = load float 169 // CHECK: %[[LHS_CONV:.+]] = fptosi float %[[LHS]] to i32 170 // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS_CONV]], i64 0 171 // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 172 // CHECK: %[[RHS:.+]] = load <4 x i32> 173 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 174 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS]] 175 176 four_ints ? four_floats : some_float; 177 // CHECK: %[[COND:.+]] = load <4 x i32> 178 // CHECK: %[[LHS:.+]] = load <4 x float> 179 // CHECK: %[[RHS:.+]] = load float 180 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[RHS]], i64 0 181 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x float> %[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 182 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer 183 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x float> %[[LHS]], <4 x float> %[[RHS_SPLAT]] 184 185 four_ll ? four_doubles : 6.0; 186 // CHECK: %[[COND:.+]] = load <4 x i64> 187 // CHECK: %[[LHS:.+]] = load <4 x double> 188 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 189 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x double> %[[LHS]], <4 x double> splat (double 6.{{.+}}) 190 191 four_ll ? four_ll : 6.0; 192 // CHECK: %[[COND:.+]] = load <4 x i64> 193 // CHECK: %[[LHS:.+]] = load <4 x i64> 194 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 195 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> splat (i64 6) 196 197 four_ll ? four_ll : 6; 198 // CHECK: %[[COND:.+]] = load <4 x i64> 199 // CHECK: %[[LHS:.+]] = load <4 x i64> 200 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 201 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> splat (i64 6) 202 203 four_ll ? four_ll : some_int; 204 // CHECK: %[[COND:.+]] = load <4 x i64> 205 // CHECK: %[[LHS:.+]] = load <4 x i64> 206 // CHECK: %[[RHS:.+]] = load i32 207 // CHECK: %[[RHS_CONV:.+]] = sext i32 %[[RHS]] to i64 208 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS_CONV]], i64 0 209 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 210 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 211 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]] 212 213 four_ll ? four_ll : some_ll; 214 // CHECK: %[[COND:.+]] = load <4 x i64> 215 // CHECK: %[[LHS:.+]] = load <4 x i64> 216 // CHECK: %[[RHS:.+]] = load i64 217 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS]], i64 0 218 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 219 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 220 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]] 221 222 four_ll ? four_ll : some_double; 223 // CHECK: %[[COND:.+]] = load <4 x i64> 224 // CHECK: %[[LHS:.+]] = load <4 x i64> 225 // CHECK: %[[RHS:.+]] = load double 226 // CHECK: %[[RHS_CONV:.+]] = fptosi double %[[RHS]] to i64 227 // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS_CONV]], i64 0 228 // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 229 // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer 230 // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]] 231 } 232