1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s 2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort | FileCheck %s 3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -mcpu=corei7-avx | FileCheck %s --check-prefix=AVX 4 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort -mcpu=corei7-avx | FileCheck %s --check-prefix=AVX 5 6 ; Test all cmp predicates that can be used with SSE. 7 8 define float @select_fcmp_oeq_f32(float %a, float %b, float %c, float %d) { 9 ; CHECK-LABEL: select_fcmp_oeq_f32 10 ; CHECK: cmpeqss %xmm1, %xmm0 11 ; CHECK-NEXT: andps %xmm0, %xmm2 12 ; CHECK-NEXT: andnps %xmm3, %xmm0 13 ; CHECK-NEXT: orps %xmm2, %xmm0 14 ; AVX-LABEL: select_fcmp_oeq_f32 15 ; AVX: vcmpeqss %xmm1, %xmm0, %xmm0 16 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 17 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 18 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 19 %1 = fcmp oeq float %a, %b 20 %2 = select i1 %1, float %c, float %d 21 ret float %2 22 } 23 24 define double @select_fcmp_oeq_f64(double %a, double %b, double %c, double %d) { 25 ; CHECK-LABEL: select_fcmp_oeq_f64 26 ; CHECK: cmpeqsd %xmm1, %xmm0 27 ; CHECK-NEXT: andpd %xmm0, %xmm2 28 ; CHECK-NEXT: andnpd %xmm3, %xmm0 29 ; CHECK-NEXT: orpd %xmm2, %xmm0 30 ; AVX-LABEL: select_fcmp_oeq_f64 31 ; AVX: vcmpeqsd %xmm1, %xmm0, %xmm0 32 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 33 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 34 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 35 %1 = fcmp oeq double %a, %b 36 %2 = select i1 %1, double %c, double %d 37 ret double %2 38 } 39 40 define float @select_fcmp_ogt_f32(float %a, float %b, float %c, float %d) { 41 ; CHECK-LABEL: select_fcmp_ogt_f32 42 ; CHECK: cmpltss %xmm0, %xmm1 43 ; CHECK-NEXT: andps %xmm1, %xmm2 44 ; CHECK-NEXT: andnps %xmm3, %xmm1 45 ; CHECK-NEXT: orps %xmm2, %xmm1 46 ; AVX-LABEL: select_fcmp_ogt_f32 47 ; AVX: vcmpltss %xmm0, %xmm1, %xmm0 48 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 49 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 50 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 51 %1 = fcmp ogt float %a, %b 52 %2 = select i1 %1, float %c, float %d 53 ret float %2 54 } 55 56 define double @select_fcmp_ogt_f64(double %a, double %b, double %c, double %d) { 57 ; CHECK-LABEL: select_fcmp_ogt_f64 58 ; CHECK: cmpltsd %xmm0, %xmm1 59 ; CHECK-NEXT: andpd %xmm1, %xmm2 60 ; CHECK-NEXT: andnpd %xmm3, %xmm1 61 ; CHECK-NEXT: orpd %xmm2, %xmm1 62 ; AVX-LABEL: select_fcmp_ogt_f64 63 ; AVX: vcmpltsd %xmm0, %xmm1, %xmm0 64 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 65 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 66 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 67 %1 = fcmp ogt double %a, %b 68 %2 = select i1 %1, double %c, double %d 69 ret double %2 70 } 71 72 define float @select_fcmp_oge_f32(float %a, float %b, float %c, float %d) { 73 ; CHECK-LABEL: select_fcmp_oge_f32 74 ; CHECK: cmpless %xmm0, %xmm1 75 ; CHECK-NEXT: andps %xmm1, %xmm2 76 ; CHECK-NEXT: andnps %xmm3, %xmm1 77 ; CHECK-NEXT: orps %xmm2, %xmm1 78 ; AVX-LABEL: select_fcmp_oge_f32 79 ; AVX: vcmpless %xmm0, %xmm1, %xmm0 80 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 81 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 82 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 83 %1 = fcmp oge float %a, %b 84 %2 = select i1 %1, float %c, float %d 85 ret float %2 86 } 87 88 define double @select_fcmp_oge_f64(double %a, double %b, double %c, double %d) { 89 ; CHECK-LABEL: select_fcmp_oge_f64 90 ; CHECK: cmplesd %xmm0, %xmm1 91 ; CHECK-NEXT: andpd %xmm1, %xmm2 92 ; CHECK-NEXT: andnpd %xmm3, %xmm1 93 ; CHECK-NEXT: orpd %xmm2, %xmm1 94 ; AVX-LABEL: select_fcmp_oge_f64 95 ; AVX: vcmplesd %xmm0, %xmm1, %xmm0 96 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 97 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 98 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 99 %1 = fcmp oge double %a, %b 100 %2 = select i1 %1, double %c, double %d 101 ret double %2 102 } 103 104 define float @select_fcmp_olt_f32(float %a, float %b, float %c, float %d) { 105 ; CHECK-LABEL: select_fcmp_olt_f32 106 ; CHECK: cmpltss %xmm1, %xmm0 107 ; CHECK-NEXT: andps %xmm0, %xmm2 108 ; CHECK-NEXT: andnps %xmm3, %xmm0 109 ; CHECK-NEXT: orps %xmm2, %xmm0 110 ; AVX-LABEL: select_fcmp_olt_f32 111 ; AVX: vcmpltss %xmm1, %xmm0, %xmm0 112 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 113 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 114 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 115 %1 = fcmp olt float %a, %b 116 %2 = select i1 %1, float %c, float %d 117 ret float %2 118 } 119 120 define double @select_fcmp_olt_f64(double %a, double %b, double %c, double %d) { 121 ; CHECK-LABEL: select_fcmp_olt_f64 122 ; CHECK: cmpltsd %xmm1, %xmm0 123 ; CHECK-NEXT: andpd %xmm0, %xmm2 124 ; CHECK-NEXT: andnpd %xmm3, %xmm0 125 ; CHECK-NEXT: orpd %xmm2, %xmm0 126 ; AVX-LABEL: select_fcmp_olt_f64 127 ; AVX: vcmpltsd %xmm1, %xmm0, %xmm0 128 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 129 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 130 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 131 %1 = fcmp olt double %a, %b 132 %2 = select i1 %1, double %c, double %d 133 ret double %2 134 } 135 136 define float @select_fcmp_ole_f32(float %a, float %b, float %c, float %d) { 137 ; CHECK-LABEL: select_fcmp_ole_f32 138 ; CHECK: cmpless %xmm1, %xmm0 139 ; CHECK-NEXT: andps %xmm0, %xmm2 140 ; CHECK-NEXT: andnps %xmm3, %xmm0 141 ; CHECK-NEXT: orps %xmm2, %xmm0 142 ; AVX-LABEL: select_fcmp_ole_f32 143 ; AVX: vcmpless %xmm1, %xmm0, %xmm0 144 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 145 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 146 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 147 %1 = fcmp ole float %a, %b 148 %2 = select i1 %1, float %c, float %d 149 ret float %2 150 } 151 152 define double @select_fcmp_ole_f64(double %a, double %b, double %c, double %d) { 153 ; CHECK-LABEL: select_fcmp_ole_f64 154 ; CHECK: cmplesd %xmm1, %xmm0 155 ; CHECK-NEXT: andpd %xmm0, %xmm2 156 ; CHECK-NEXT: andnpd %xmm3, %xmm0 157 ; CHECK-NEXT: orpd %xmm2, %xmm0 158 ; AVX-LABEL: select_fcmp_ole_f64 159 ; AVX: vcmplesd %xmm1, %xmm0, %xmm0 160 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 161 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 162 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 163 %1 = fcmp ole double %a, %b 164 %2 = select i1 %1, double %c, double %d 165 ret double %2 166 } 167 168 define float @select_fcmp_ord_f32(float %a, float %b, float %c, float %d) { 169 ; CHECK-LABEL: select_fcmp_ord_f32 170 ; CHECK: cmpordss %xmm1, %xmm0 171 ; CHECK-NEXT: andps %xmm0, %xmm2 172 ; CHECK-NEXT: andnps %xmm3, %xmm0 173 ; CHECK-NEXT: orps %xmm2, %xmm0 174 ; AVX-LABEL: select_fcmp_ord_f32 175 ; AVX: vcmpordss %xmm1, %xmm0, %xmm0 176 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 177 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 178 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 179 %1 = fcmp ord float %a, %b 180 %2 = select i1 %1, float %c, float %d 181 ret float %2 182 } 183 184 define double @select_fcmp_ord_f64(double %a, double %b, double %c, double %d) { 185 ; CHECK-LABEL: select_fcmp_ord_f64 186 ; CHECK: cmpordsd %xmm1, %xmm0 187 ; CHECK-NEXT: andpd %xmm0, %xmm2 188 ; CHECK-NEXT: andnpd %xmm3, %xmm0 189 ; CHECK-NEXT: orpd %xmm2, %xmm0 190 ; AVX-LABEL: select_fcmp_ord_f64 191 ; AVX: vcmpordsd %xmm1, %xmm0, %xmm0 192 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 193 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 194 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 195 %1 = fcmp ord double %a, %b 196 %2 = select i1 %1, double %c, double %d 197 ret double %2 198 } 199 200 define float @select_fcmp_uno_f32(float %a, float %b, float %c, float %d) { 201 ; CHECK-LABEL: select_fcmp_uno_f32 202 ; CHECK: cmpunordss %xmm1, %xmm0 203 ; CHECK-NEXT: andps %xmm0, %xmm2 204 ; CHECK-NEXT: andnps %xmm3, %xmm0 205 ; CHECK-NEXT: orps %xmm2, %xmm0 206 ; AVX-LABEL: select_fcmp_uno_f32 207 ; AVX: vcmpunordss %xmm1, %xmm0, %xmm0 208 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 209 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 210 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 211 %1 = fcmp uno float %a, %b 212 %2 = select i1 %1, float %c, float %d 213 ret float %2 214 } 215 216 define double @select_fcmp_uno_f64(double %a, double %b, double %c, double %d) { 217 ; CHECK-LABEL: select_fcmp_uno_f64 218 ; CHECK: cmpunordsd %xmm1, %xmm0 219 ; CHECK-NEXT: andpd %xmm0, %xmm2 220 ; CHECK-NEXT: andnpd %xmm3, %xmm0 221 ; CHECK-NEXT: orpd %xmm2, %xmm0 222 ; AVX-LABEL: select_fcmp_uno_f64 223 ; AVX: vcmpunordsd %xmm1, %xmm0, %xmm0 224 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 225 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 226 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 227 %1 = fcmp uno double %a, %b 228 %2 = select i1 %1, double %c, double %d 229 ret double %2 230 } 231 232 define float @select_fcmp_ugt_f32(float %a, float %b, float %c, float %d) { 233 ; CHECK-LABEL: select_fcmp_ugt_f32 234 ; CHECK: cmpnless %xmm1, %xmm0 235 ; CHECK-NEXT: andps %xmm0, %xmm2 236 ; CHECK-NEXT: andnps %xmm3, %xmm0 237 ; CHECK-NEXT: orps %xmm2, %xmm0 238 ; AVX-LABEL: select_fcmp_ugt_f32 239 ; AVX: vcmpnless %xmm1, %xmm0, %xmm0 240 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 241 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 242 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 243 %1 = fcmp ugt float %a, %b 244 %2 = select i1 %1, float %c, float %d 245 ret float %2 246 } 247 248 define double @select_fcmp_ugt_f64(double %a, double %b, double %c, double %d) { 249 ; CHECK-LABEL: select_fcmp_ugt_f64 250 ; CHECK: cmpnlesd %xmm1, %xmm0 251 ; CHECK-NEXT: andpd %xmm0, %xmm2 252 ; CHECK-NEXT: andnpd %xmm3, %xmm0 253 ; CHECK-NEXT: orpd %xmm2, %xmm0 254 ; AVX-LABEL: select_fcmp_ugt_f64 255 ; AVX: vcmpnlesd %xmm1, %xmm0, %xmm0 256 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 257 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 258 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 259 %1 = fcmp ugt double %a, %b 260 %2 = select i1 %1, double %c, double %d 261 ret double %2 262 } 263 264 define float @select_fcmp_uge_f32(float %a, float %b, float %c, float %d) { 265 ; CHECK-LABEL: select_fcmp_uge_f32 266 ; CHECK: cmpnltss %xmm1, %xmm0 267 ; CHECK-NEXT: andps %xmm0, %xmm2 268 ; CHECK-NEXT: andnps %xmm3, %xmm0 269 ; CHECK-NEXT: orps %xmm2, %xmm0 270 ; AVX-LABEL: select_fcmp_uge_f32 271 ; AVX: vcmpnltss %xmm1, %xmm0, %xmm0 272 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 273 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 274 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 275 %1 = fcmp uge float %a, %b 276 %2 = select i1 %1, float %c, float %d 277 ret float %2 278 } 279 280 define double @select_fcmp_uge_f64(double %a, double %b, double %c, double %d) { 281 ; CHECK-LABEL: select_fcmp_uge_f64 282 ; CHECK: cmpnltsd %xmm1, %xmm0 283 ; CHECK-NEXT: andpd %xmm0, %xmm2 284 ; CHECK-NEXT: andnpd %xmm3, %xmm0 285 ; CHECK-NEXT: orpd %xmm2, %xmm0 286 ; AVX-LABEL: select_fcmp_uge_f64 287 ; AVX: vcmpnltsd %xmm1, %xmm0, %xmm0 288 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 289 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 290 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 291 %1 = fcmp uge double %a, %b 292 %2 = select i1 %1, double %c, double %d 293 ret double %2 294 } 295 296 define float @select_fcmp_ult_f32(float %a, float %b, float %c, float %d) { 297 ; CHECK-LABEL: select_fcmp_ult_f32 298 ; CHECK: cmpnless %xmm0, %xmm1 299 ; CHECK-NEXT: andps %xmm1, %xmm2 300 ; CHECK-NEXT: andnps %xmm3, %xmm1 301 ; CHECK-NEXT: orps %xmm2, %xmm1 302 ; AVX-LABEL: select_fcmp_ult_f32 303 ; AVX: vcmpnless %xmm0, %xmm1, %xmm0 304 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 305 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 306 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 307 %1 = fcmp ult float %a, %b 308 %2 = select i1 %1, float %c, float %d 309 ret float %2 310 } 311 312 define double @select_fcmp_ult_f64(double %a, double %b, double %c, double %d) { 313 ; CHECK-LABEL: select_fcmp_ult_f64 314 ; CHECK: cmpnlesd %xmm0, %xmm1 315 ; CHECK-NEXT: andpd %xmm1, %xmm2 316 ; CHECK-NEXT: andnpd %xmm3, %xmm1 317 ; CHECK-NEXT: orpd %xmm2, %xmm1 318 ; AVX-LABEL: select_fcmp_ult_f64 319 ; AVX: vcmpnlesd %xmm0, %xmm1, %xmm0 320 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 321 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 322 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 323 %1 = fcmp ult double %a, %b 324 %2 = select i1 %1, double %c, double %d 325 ret double %2 326 } 327 328 define float @select_fcmp_ule_f32(float %a, float %b, float %c, float %d) { 329 ; CHECK-LABEL: select_fcmp_ule_f32 330 ; CHECK: cmpnltss %xmm0, %xmm1 331 ; CHECK-NEXT: andps %xmm1, %xmm2 332 ; CHECK-NEXT: andnps %xmm3, %xmm1 333 ; CHECK-NEXT: orps %xmm2, %xmm1 334 ; AVX-LABEL: select_fcmp_ule_f32 335 ; AVX: vcmpnltss %xmm0, %xmm1, %xmm0 336 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 337 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 338 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 339 %1 = fcmp ule float %a, %b 340 %2 = select i1 %1, float %c, float %d 341 ret float %2 342 } 343 344 define double @select_fcmp_ule_f64(double %a, double %b, double %c, double %d) { 345 ; CHECK-LABEL: select_fcmp_ule_f64 346 ; CHECK: cmpnltsd %xmm0, %xmm1 347 ; CHECK-NEXT: andpd %xmm1, %xmm2 348 ; CHECK-NEXT: andnpd %xmm3, %xmm1 349 ; CHECK-NEXT: orpd %xmm2, %xmm1 350 ; AVX-LABEL: select_fcmp_ule_f64 351 ; AVX: vcmpnltsd %xmm0, %xmm1, %xmm0 352 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 353 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 354 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 355 %1 = fcmp ule double %a, %b 356 %2 = select i1 %1, double %c, double %d 357 ret double %2 358 } 359 360 define float @select_fcmp_une_f32(float %a, float %b, float %c, float %d) { 361 ; CHECK-LABEL: select_fcmp_une_f32 362 ; CHECK: cmpneqss %xmm1, %xmm0 363 ; CHECK-NEXT: andps %xmm0, %xmm2 364 ; CHECK-NEXT: andnps %xmm3, %xmm0 365 ; CHECK-NEXT: orps %xmm2, %xmm0 366 ; AVX-LABEL: select_fcmp_une_f32 367 ; AVX: vcmpneqss %xmm1, %xmm0, %xmm0 368 ; AVX-NEXT: vandps %xmm2, %xmm0, %xmm1 369 ; AVX-NEXT: vandnps %xmm3, %xmm0, %xmm0 370 ; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0 371 %1 = fcmp une float %a, %b 372 %2 = select i1 %1, float %c, float %d 373 ret float %2 374 } 375 376 define double @select_fcmp_une_f64(double %a, double %b, double %c, double %d) { 377 ; CHECK-LABEL: select_fcmp_une_f64 378 ; CHECK: cmpneqsd %xmm1, %xmm0 379 ; CHECK-NEXT: andpd %xmm0, %xmm2 380 ; CHECK-NEXT: andnpd %xmm3, %xmm0 381 ; CHECK-NEXT: orpd %xmm2, %xmm0 382 ; AVX-LABEL: select_fcmp_une_f64 383 ; AVX: vcmpneqsd %xmm1, %xmm0, %xmm0 384 ; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm1 385 ; AVX-NEXT: vandnpd %xmm3, %xmm0, %xmm0 386 ; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0 387 %1 = fcmp une double %a, %b 388 %2 = select i1 %1, double %c, double %d 389 ret double %2 390 } 391 392