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__((ext_vector_type(4))); 4 using TwoInts = int __attribute__((ext_vector_type(2))); 5 using TwoUInts = unsigned __attribute__((ext_vector_type(2))); 6 using FourInts = int __attribute__((ext_vector_type(4))); 7 using FourUInts = unsigned __attribute__((ext_vector_type(4))); 8 using TwoLongLong = long long __attribute__((ext_vector_type(2))); 9 using FourLongLong = long long __attribute__((ext_vector_type(4))); 10 using TwoFloats = float __attribute__((ext_vector_type(2))); 11 using FourFloats = float __attribute__((ext_vector_type(4))); 12 using TwoDoubles = double __attribute__((ext_vector_type(2))); 13 using FourDoubles = double __attribute__((ext_vector_type(4))); 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: [[NEG:%.+]] = icmp slt <2 x i32> [[COND]], zeroinitializer 43 // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i32> 44 // CHECK: [[XOR:%.+]] = xor <2 x i32> [[SEXT]], splat (i32 -1) 45 // CHECK: [[RHS_AND:%.+]] = and <2 x i32> [[RHS]], [[XOR]] 46 // CHECK: [[LHS_AND:%.+]] = and <2 x i32> [[LHS]], [[SEXT]] 47 // CHECK: = or <2 x i32> [[RHS_AND]], [[LHS_AND]] 48 49 two_ints ? two_floats : two_floats; 50 // CHECK: [[COND:%.+]] = load <2 x i32> 51 // CHECK: [[LHS:%.+]] = load <2 x float> 52 // CHECK: [[RHS:%.+]] = load <2 x float> 53 // CHECK: [[NEG:%.+]] = icmp slt <2 x i32> [[COND]], zeroinitializer 54 // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i32> 55 // CHECK: [[XOR:%.+]] = xor <2 x i32> [[SEXT]], splat (i32 -1) 56 // CHECK: [[RHS_EXT:%.+]] = bitcast <2 x float> [[RHS]] to <2 x i32> 57 // CHECK: [[LHS_EXT:%.+]] = bitcast <2 x float> [[LHS]] to <2 x i32> 58 // CHECK: [[RHS_AND:%.+]] = and <2 x i32> [[RHS_EXT]], [[XOR]] 59 // CHECK: [[LHS_AND:%.+]] = and <2 x i32> [[LHS_EXT]], [[SEXT]] 60 // CHECK: [[OR:%.+]] = or <2 x i32> [[RHS_AND]], [[LHS_AND]] 61 // CHECK: = bitcast <2 x i32> [[OR]] to <2 x float> 62 63 two_ll ? two_doubles : two_doubles; 64 // CHECK: [[COND:%.+]] = load <2 x i64> 65 // CHECK: [[LHS:%.+]] = load <2 x double> 66 // CHECK: [[RHS:%.+]] = load <2 x double> 67 // CHECK: [[NEG:%.+]] = icmp slt <2 x i64> [[COND]], zeroinitializer 68 // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i64> 69 // CHECK: [[XOR:%.+]] = xor <2 x i64> [[SEXT]], splat (i64 -1) 70 // CHECK: [[RHS_EXT:%.+]] = bitcast <2 x double> [[RHS]] to <2 x i64> 71 // CHECK: [[LHS_EXT:%.+]] = bitcast <2 x double> [[LHS]] to <2 x i64> 72 // CHECK: [[RHS_AND:%.+]] = and <2 x i64> [[RHS_EXT]], [[XOR]] 73 // CHECK: [[LHS_AND:%.+]] = and <2 x i64> [[LHS_EXT]], [[SEXT]] 74 // CHECK: [[OR:%.+]] = or <2 x i64> [[RHS_AND]], [[LHS_AND]] 75 // CHECK: = bitcast <2 x i64> [[OR]] to <2 x double> 76 } 77 78 // CHECK: TwoScalarOps 79 void TwoScalarOps() { 80 four_shorts ? some_short : some_short; 81 // CHECK: [[COND:%.+]] = load <4 x i16> 82 // CHECK: [[LHS:%.+]] = load i16 83 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 [[LHS]], i64 0 84 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i16> [[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 85 // CHECK: [[RHS:%.+]] = load i16 86 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 [[RHS]], i64 0 87 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i16> [[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 88 // CHECK: [[NEG:%.+]] = icmp slt <4 x i16> [[COND]], zeroinitializer 89 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i16> 90 // CHECK: [[XOR:%.+]] = xor <4 x i16> [[SEXT]], splat (i16 -1) 91 // CHECK: [[RHS_AND:%.+]] = and <4 x i16> [[RHS_SPLAT]], [[XOR]] 92 // CHECK: [[LHS_AND:%.+]] = and <4 x i16> [[LHS_SPLAT]], [[SEXT]] 93 // CHECK: = or <4 x i16> [[RHS_AND]], [[LHS_AND]] 94 95 four_shorts ? some_ushort : some_ushort; 96 // CHECK: [[COND:%.+]] = load <4 x i16> 97 // CHECK: [[LHS:%.+]] = load i16 98 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 [[LHS]], i64 0 99 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i16> [[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 100 // CHECK: [[RHS:%.+]] = load i16 101 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 [[RHS]], i64 0 102 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i16> [[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer 103 // CHECK: [[NEG:%.+]] = icmp slt <4 x i16> [[COND]], zeroinitializer 104 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i16> 105 // CHECK: [[XOR:%.+]] = xor <4 x i16> [[SEXT]], splat (i16 -1) 106 // CHECK: [[RHS_AND:%.+]] = and <4 x i16> [[RHS_SPLAT]], [[XOR]] 107 // CHECK: [[LHS_AND:%.+]] = and <4 x i16> [[LHS_SPLAT]], [[SEXT]] 108 // CHECK: = or <4 x i16> [[RHS_AND]], [[LHS_AND]] 109 110 four_ints ? some_ushort : some_short; 111 // CHECK: [[COND:%.+]] = load <4 x i32> 112 // CHECK: [[LHS:%.+]] = load i16 113 // CHECK: [[LHS_ZEXT:%.+]] = zext i16 [[LHS]] to i32 114 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 [[LHS_ZEXT]], i64 0 115 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i32> [[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 116 // CHECK: [[RHS:%.+]] = load i16 117 // CHECK: [[RHS_SEXT:%.+]] = sext i16 [[RHS]] to i32 118 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 [[RHS_SEXT]], i64 0 119 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 120 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 121 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 122 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 123 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]] 124 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_SPLAT]], [[SEXT]] 125 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 126 127 four_ints ? some_int : some_float; 128 // CHECK: [[COND:%.+]] = load <4 x i32> 129 // CHECK: [[LHS:%.+]] = load i32 130 // CHECK: [[LHS_CONV:%.+]] = sitofp i32 [[LHS]] to float 131 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float [[LHS_CONV]], i64 0 132 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x float> [[LHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 133 // CHECK: [[RHS:%.+]] = load float 134 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float [[RHS]], i64 0 135 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x float> [[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 136 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 137 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 138 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 139 // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x float> [[RHS_SPLAT]] to <4 x i32> 140 // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x float> [[LHS_SPLAT]] to <4 x i32> 141 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_CAST]], [[XOR]] 142 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_CAST]], [[SEXT]] 143 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 144 145 four_ll ? some_double : some_ll; 146 // CHECK: [[COND:%.+]] = load <4 x i64> 147 // CHECK: [[LHS:%.+]] = load double 148 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x double> poison, double [[LHS]], i64 0 149 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x double> [[LHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer 150 // CHECK: [[RHS:%.+]] = load i64 151 // CHECK: [[RHS_CONV:%.+]] = sitofp i64 [[RHS]] to double 152 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x double> poison, double [[RHS_CONV]], i64 0 153 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x double> [[RHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer 154 // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer 155 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64> 156 // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1) 157 // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x double> [[RHS_SPLAT]] to <4 x i64> 158 // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x double> [[LHS_SPLAT]] to <4 x i64> 159 // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_CAST]], [[XOR]] 160 // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS_CAST]], [[SEXT]] 161 // CHECK: = or <4 x i64> [[RHS_AND]], [[LHS_AND]] 162 163 four_ints ? some_int : some_short; 164 // CHECK: [[COND:%.+]] = load <4 x i32> 165 // CHECK: [[LHS:%.+]] = load i32 166 // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 [[LHS]], i64 0 167 // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i32> [[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 168 // CHECK: [[RHS:%.+]] = load i16 169 // CHECK: [[RHS_SEXT:%.+]] = sext i16 [[RHS]] to i32 170 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 [[RHS_SEXT]], i64 0 171 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 172 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 173 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 174 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 175 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]] 176 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_SPLAT]], [[SEXT]] 177 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 178 } 179 180 // CHECK: OneScalarOp 181 void OneScalarOp() { 182 four_ints ? four_ints : some_int; 183 // CHECK: [[COND:%.+]] = load <4 x i32> 184 // CHECK: [[LHS:%.+]] = load <4 x i32> 185 // CHECK: [[RHS:%.+]] = load i32 186 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 [[RHS]], i64 0 187 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer 188 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 189 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 190 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 191 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]] 192 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS]], [[SEXT]] 193 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 194 195 four_ints ? four_ints : 5; 196 // CHECK: [[COND:%.+]] = load <4 x i32> 197 // CHECK: [[LHS:%.+]] = load <4 x i32> 198 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 199 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 200 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 201 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> splat (i32 5), [[XOR]] 202 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS]], [[SEXT]] 203 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 204 205 four_ints ? four_floats : some_float; 206 // CHECK: [[COND:%.+]] = load <4 x i32> 207 // CHECK: [[LHS:%.+]] = load <4 x float> 208 // CHECK: [[RHS:%.+]] = load float 209 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float [[RHS]], i64 0 210 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x float> [[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer 211 // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer 212 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32> 213 // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1) 214 // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x float> [[RHS_SPLAT]] to <4 x i32> 215 // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x float> [[LHS]] to <4 x i32> 216 // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_CAST]], [[XOR]] 217 // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_CAST]], [[SEXT]] 218 // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]] 219 220 four_ll ? four_doubles : 6.0; 221 // CHECK: [[COND:%.+]] = load <4 x i64> 222 // CHECK: [[LHS:%.+]] = load <4 x double> 223 // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer 224 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64> 225 // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1) 226 // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x double> [[LHS]] to <4 x i64> 227 // CHECK: [[RHS_AND:%.+]] = and <4 x i64> splat (i64 4618441417868443648), [[XOR]] 228 // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS_CAST]], [[SEXT]] 229 // CHECK: = or <4 x i64> [[RHS_AND]], [[LHS_AND]] 230 231 four_ll ? four_ll : 6; 232 // CHECK: [[COND:%.+]] = load <4 x i64> 233 // CHECK: [[LHS:%.+]] = load <4 x i64> 234 // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer 235 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64> 236 // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1) 237 // CHECK: [[RHS_AND:%.+]] = and <4 x i64> splat (i64 6), [[XOR]] 238 // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]] 239 // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]] 240 241 four_ll ? four_ll : some_int; 242 // CHECK: [[COND:%.+]] = load <4 x i64> 243 // CHECK: [[LHS:%.+]] = load <4 x i64> 244 // CHECK: [[RHS:%.+]] = load i32 245 // CHECK: [[RHS_CONV:%.+]] = sext i32 [[RHS]] to i64 246 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i64> poison, i64 [[RHS_CONV]], i64 0 247 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i64> [[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 248 // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer 249 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64> 250 // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1) 251 // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_SPLAT]], [[XOR]] 252 // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]] 253 // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]] 254 255 four_ll ? four_ll : some_ll; 256 // CHECK: [[COND:%.+]] = load <4 x i64> 257 // CHECK: [[LHS:%.+]] = load <4 x i64> 258 // CHECK: [[RHS:%.+]] = load i64 259 // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i64> poison, i64 [[RHS]], i64 0 260 // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i64> [[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 261 // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer 262 // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64> 263 // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1) 264 // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_SPLAT]], [[XOR]] 265 // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]] 266 // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]] 267 } 268