1 ; This tries to be a comprehensive test of f32 and f64 compare operations. 2 3 ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 \ 4 ; RUN: -allow-externally-defined-symbols | FileCheck %s 5 ; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 \ 6 ; RUN: -allow-externally-defined-symbols | FileCheck %s \ 7 ; RUN: --check-prefix=CHECK-OM1 8 9 ; RUN: %if --need=target_ARM32 --command %p2i --filetype=obj --disassemble \ 10 ; RUN: --target arm32 -i %s --args -O2 \ 11 ; RUN: -allow-externally-defined-symbols \ 12 ; RUN: | %if --need=target_ARM32 --command FileCheck %s \ 13 ; RUN: --check-prefix=ARM32 --check-prefix=ARM32-O2 14 15 ; RUN: %if --need=target_ARM32 --command %p2i --filetype=obj --disassemble \ 16 ; RUN: --target arm32 -i %s --args -Om1 \ 17 ; RUN: -allow-externally-defined-symbols \ 18 ; RUN: | %if --need=target_ARM32 --command FileCheck %s \ 19 ; RUN: --check-prefix=ARM32 --check-prefix=ARM32-OM1 20 21 ; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i \ 22 ; RUN: --filetype=asm --target mips32 -i %s --args -Om1 \ 23 ; RUN: -allow-externally-defined-symbols \ 24 ; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \ 25 ; RUN: --check-prefix=MIPS32 26 27 define internal void @fcmpEq(float %a, float %b, double %c, double %d) { 28 entry: 29 %cmp = fcmp oeq float %a, %b 30 br i1 %cmp, label %if.then, label %if.end 31 32 if.then: ; preds = %entry 33 call void @func() 34 br label %if.end 35 36 if.end: ; preds = %if.then, %entry 37 %cmp1 = fcmp oeq double %c, %d 38 br i1 %cmp1, label %if.then2, label %if.end3 39 40 if.then2: ; preds = %if.end 41 call void @func() 42 br label %if.end3 43 44 if.end3: ; preds = %if.then2, %if.end 45 ret void 46 } 47 ; CHECK-LABEL: fcmpEq 48 ; CHECK: ucomiss 49 ; CHECK-NEXT: jne 50 ; CHECK-NEXT: jp 51 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 52 ; CHECK: ucomisd 53 ; CHECK-NEXT: jne 54 ; CHECK-NEXT: jp 55 ; CHECK: call {{.*}} R_{{.*}} func 56 ; CHECK-OM1-LABEL: fcmpEq 57 ; CHECK-OM1: ucomiss 58 ; CHECK-OM1: jne 59 ; CHECK-OM1-NEXT: jp 60 ; CHECK-OM1: call {{.*}} R_{{.*}} func 61 ; CHECK-OM1: ucomisd 62 ; CHECK-OM1: jne 63 ; CHECK-NEXT-OM1: jp 64 ; ARM32-LABEL: fcmpEq 65 ; ARM32: vcmp.f32 66 ; ARM32: vmrs 67 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 68 ; ARM32-OM1: moveq [[R0]], #1 69 ; ARM32-O2: bne 70 ; ARM32: bl{{.*}}func 71 ; ARM32: vcmp.f64 72 ; ARM32: vmrs 73 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 74 ; ARM32-OM1: moveq [[R1]], #1 75 ; ARM32-O2: bne 76 ; MIPS32-LABEL: fcmpEq 77 ; MIPS32-LABEL: .LfcmpEq$entry 78 ; MIPS32: c.eq.s 79 ; MIPS32: addiu [[REG:.*]], $zero, 1 80 ; MIPS32: movf [[REG]], $zero, {{.*}} 81 ; MIPS32-LABEL: .LfcmpEq$if.end 82 ; MIPS32: c.eq.d 83 ; MIPS32: addiu [[REG:.*]], $zero, 1 84 ; MIPS32: movf [[REG]], $zero, {{.*}} 85 86 declare void @func() 87 88 define internal void @fcmpNe(float %a, float %b, double %c, double %d) { 89 entry: 90 %cmp = fcmp une float %a, %b 91 br i1 %cmp, label %if.then, label %if.end 92 93 if.then: ; preds = %entry 94 call void @func() 95 br label %if.end 96 97 if.end: ; preds = %if.then, %entry 98 %cmp1 = fcmp une double %c, %d 99 br i1 %cmp1, label %if.then2, label %if.end3 100 101 if.then2: ; preds = %if.end 102 call void @func() 103 br label %if.end3 104 105 if.end3: ; preds = %if.then2, %if.end 106 ret void 107 } 108 ; CHECK-LABEL: fcmpNe 109 ; CHECK: ucomiss 110 ; CHECK-NEXT: jne 111 ; CHECK-NEXT: jp 112 ; CHECK-NEXT: jmp 113 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 114 ; CHECK: ucomisd 115 ; CHECK-NEXT: jne 116 ; CHECK-NEXT: jp 117 ; CHECK-NEXT: jmp 118 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 119 ; CHECK-OM1-LABEL: fcmpNe 120 ; CHECK-OM1: ucomiss 121 ; CHECK-OM1: jne 122 ; CHECK-OM1: jp 123 ; CHECK-OM1: jmp 124 ; CHECK-OM1: call {{.*}} R_{{.*}} func 125 ; CHECK-OM1: ucomisd 126 ; CHECK-OM1: jne 127 ; CHECK-OM1: jp 128 ; CHECK-OM1: jmp 129 ; CHECK-OM1: call {{.*}} R_{{.*}} func 130 ; ARM32-LABEL: fcmpNe 131 ; ARM32: vcmp.f32 132 ; ARM32: vmrs 133 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 134 ; ARM32-OM1: movne [[R0]], #1 135 ; ARM32-O2: beq 136 ; ARM32: vcmp.f64 137 ; ARM32: vmrs 138 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 139 ; ARM32-OM1: movne [[R1]], #1 140 ; ARM32-O2: beq 141 ; MIPS32-LABEL: fcmpNe 142 ; MIPS32-LABEL: .LfcmpNe$entry 143 ; MIPS32: c.eq.s 144 ; MIPS32: addiu [[REG:.*]], $zero, 1 145 ; MIPS32: movt [[REG]], $zero, {{.*}} 146 ; MIPS32-LABEL: .LfcmpNe$if.end 147 ; MIPS32: c.eq.d 148 ; MIPS32: addiu [[REG:.*]], $zero, 1 149 ; MIPS32: movt [[REG]], $zero, {{.*}} 150 151 define internal void @fcmpGt(float %a, float %b, double %c, double %d) { 152 entry: 153 %cmp = fcmp ogt float %a, %b 154 br i1 %cmp, label %if.then, label %if.end 155 156 if.then: ; preds = %entry 157 call void @func() 158 br label %if.end 159 160 if.end: ; preds = %if.then, %entry 161 %cmp1 = fcmp ogt double %c, %d 162 br i1 %cmp1, label %if.then2, label %if.end3 163 164 if.then2: ; preds = %if.end 165 call void @func() 166 br label %if.end3 167 168 if.end3: ; preds = %if.then2, %if.end 169 ret void 170 } 171 ; CHECK-LABEL: fcmpGt 172 ; CHECK: ucomiss 173 ; CHECK-NEXT: jbe 174 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 175 ; CHECK: ucomisd 176 ; CHECK-NEXT: jbe 177 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 178 ; CHECK-OM1-LABEL: fcmpGt 179 ; CHECK-OM1: ucomiss 180 ; CHECK-OM1: seta 181 ; CHECK-OM1: call {{.*}} R_{{.*}} func 182 ; CHECK-OM1: ucomisd 183 ; CHECK-OM1: seta 184 ; CHECK-OM1: call {{.*}} R_{{.*}} func 185 ; ARM32-LABEL: fcmpGt 186 ; ARM32: vcmp.f32 187 ; ARM32: vmrs 188 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 189 ; ARM32-OM1: movgt [[R0]], #1 190 ; ARM32-O2: ble 191 ; ARM32: vcmp.f64 192 ; ARM32: vmrs 193 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 194 ; ARM32-OM1: movgt [[R1]], #1 195 ; ARM32-O2: ble 196 ; MIPS32-LABEL: fcmpGt 197 ; MIPS32-LABEL: .LfcmpGt$entry 198 ; MIPS32: c.ule.s 199 ; MIPS32: addiu [[REG:.*]], $zero, 1 200 ; MIPS32: movt [[REG]], $zero, {{.*}} 201 ; MIPS32-LABEL: .LfcmpGt$if.end 202 ; MIPS32: c.ule.d 203 ; MIPS32: addiu [[REG:.*]], $zero, 1 204 ; MIPS32: movt [[REG]], $zero, {{.*}} 205 206 define internal void @fcmpGe(float %a, float %b, double %c, double %d) { 207 entry: 208 %cmp = fcmp ult float %a, %b 209 br i1 %cmp, label %if.end, label %if.then 210 211 if.then: ; preds = %entry 212 call void @func() 213 br label %if.end 214 215 if.end: ; preds = %entry, %if.then 216 %cmp1 = fcmp ult double %c, %d 217 br i1 %cmp1, label %if.end3, label %if.then2 218 219 if.then2: ; preds = %if.end 220 call void @func() 221 br label %if.end3 222 223 if.end3: ; preds = %if.end, %if.then2 224 ret void 225 } 226 ; CHECK-LABEL: fcmpGe 227 ; CHECK: ucomiss 228 ; CHECK-NEXT: jb 229 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 230 ; CHECK: ucomisd 231 ; CHECK-NEXT: jb 232 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 233 ; CHECK-OM1-LABEL: fcmpGe 234 ; CHECK-OM1: ucomiss 235 ; CHECK-OM1-NEXT: setb 236 ; CHECK-OM1: call {{.*}} R_{{.*}} func 237 ; CHECK-OM1: ucomisd 238 ; CHECK-OM1-NEXT: setb 239 ; CHECK-OM1: call {{.*}} R_{{.*}} func 240 ; ARM32-LABEL: fcmpGe 241 ; ARM32: vcmp.f32 242 ; ARM32: vmrs 243 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 244 ; ARM32-OM1: movlt [[R0]], #1 245 ; ARM32-O2: blt 246 ; ARM32: vcmp.f64 247 ; ARM32: vmrs 248 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 249 ; ARM32-OM1: movlt [[R1]], #1 250 ; ARM32-O2: blt 251 ; MIPS32-LABEL: fcmpGe 252 ; MIPS32-LABEL: .LfcmpGe$entry 253 ; MIPS32: c.ult.s 254 ; MIPS32: addiu [[REG:.*]], $zero, 1 255 ; MIPS32: movf [[REG]], $zero, {{.*}} 256 ; MIPS32-LABEL: .LfcmpGe$if.end 257 ; MIPS32: c.ult.d 258 ; MIPS32: addiu [[REG:.*]], $zero, 1 259 ; MIPS32: movf [[REG]], $zero, {{.*}} 260 261 define internal void @fcmpLt(float %a, float %b, double %c, double %d) { 262 entry: 263 %cmp = fcmp olt float %a, %b 264 br i1 %cmp, label %if.then, label %if.end 265 266 if.then: ; preds = %entry 267 call void @func() 268 br label %if.end 269 270 if.end: ; preds = %if.then, %entry 271 %cmp1 = fcmp olt double %c, %d 272 br i1 %cmp1, label %if.then2, label %if.end3 273 274 if.then2: ; preds = %if.end 275 call void @func() 276 br label %if.end3 277 278 if.end3: ; preds = %if.then2, %if.end 279 ret void 280 } 281 ; CHECK-LABEL: fcmpLt 282 ; CHECK: ucomiss 283 ; CHECK-NEXT: jbe 284 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 285 ; CHECK: ucomisd 286 ; CHECK-NEXT: jbe 287 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 288 ; CHECK-OM1-LABEL: fcmpLt 289 ; CHECK-OM1: ucomiss 290 ; CHECK-OM1-NEXT: seta 291 ; CHECK-OM1: call {{.*}} R_{{.*}} func 292 ; CHECK-OM1: ucomisd 293 ; CHECK-OM1-NEXT: seta 294 ; CHECK-OM1: call {{.*}} R_{{.*}} func 295 ; ARM32-LABEL: fcmpLt 296 ; ARM32: vcmp.f32 297 ; ARM32: vmrs 298 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 299 ; ARM32-OM1: movmi [[R0]], #1 300 ; ARM32-O2: bpl 301 ; ARM32: vcmp.f64 302 ; ARM32: vmrs 303 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 304 ; ARM32-OM1: movmi [[R1]], #1 305 ; ARM32-O2: bpl 306 ; MIPS32-LABEL: fcmpLt 307 ; MIPS32-LABEL: .LfcmpLt$entry 308 ; MIPS32: c.olt.s 309 ; MIPS32: addiu [[REG:.*]], $zero, 1 310 ; MIPS32: movf [[REG]], $zero, {{.*}} 311 ; MIPS32-LABEL: .LfcmpLt$if.end 312 ; MIPS32: c.olt.d 313 ; MIPS32: addiu [[REG:.*]], $zero, 1 314 ; MIPS32: movf [[REG]], $zero, {{.*}} 315 316 define internal void @fcmpLe(float %a, float %b, double %c, double %d) { 317 entry: 318 %cmp = fcmp ugt float %a, %b 319 br i1 %cmp, label %if.end, label %if.then 320 321 if.then: ; preds = %entry 322 call void @func() 323 br label %if.end 324 325 if.end: ; preds = %entry, %if.then 326 %cmp1 = fcmp ugt double %c, %d 327 br i1 %cmp1, label %if.end3, label %if.then2 328 329 if.then2: ; preds = %if.end 330 call void @func() 331 br label %if.end3 332 333 if.end3: ; preds = %if.end, %if.then2 334 ret void 335 } 336 ; CHECK-LABEL: fcmpLe 337 ; CHECK: ucomiss 338 ; CHECK-NEXT: jb 339 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 340 ; CHECK: ucomisd 341 ; CHECK-NEXT: jb 342 ; CHECK-NEXT: call {{.*}} R_{{.*}} func 343 ; CHECK-OM1-LABEL: fcmpLe 344 ; CHECK-OM1: ucomiss 345 ; CHECK-OM1-NEXT: setb 346 ; CHECK-OM1: call {{.*}} R_{{.*}} func 347 ; CHECK-OM1: ucomisd 348 ; CHECK-OM1-NEXT: setb 349 ; CHECK-OM1: call {{.*}} R_{{.*}} func 350 ; ARM32-LABEL: fcmpLe 351 ; ARM32: vcmp.f32 352 ; ARM32: vmrs 353 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0 354 ; ARM32-OM1: movhi [[R0]], #1 355 ; ARM32-O2: bhi 356 ; ARM32: vcmp.f64 357 ; ARM32: vmrs 358 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 359 ; ARM32-OM1: movhi [[R1]], #1 360 ; ARM32-O2: bhi 361 ; MIPS32-LABEL: fcmpLe 362 ; MIPS32-LABEL: .LfcmpLe$entry 363 ; MIPS32: c.ole.s 364 ; MIPS32: addiu [[REG:.*]], $zero, 1 365 ; MIPS32: movt [[REG]], $zero, {{.*}} 366 ; MIPS32-LABEL: .LfcmpLe$if.end 367 ; MIPS32: c.ole.d 368 ; MIPS32: addiu [[REG:.*]], $zero, 1 369 ; MIPS32: movt [[REG]], $zero, {{.*}} 370 371 define internal i32 @fcmpFalseFloat(float %a, float %b) { 372 entry: 373 %cmp = fcmp false float %a, %b 374 %cmp.ret_ext = zext i1 %cmp to i32 375 ret i32 %cmp.ret_ext 376 } 377 ; CHECK-LABEL: fcmpFalseFloat 378 ; CHECK: mov {{.*}},0x0 379 ; ARM32-LABEL: fcmpFalseFloat 380 ; ARM32: mov [[R:r[0-9]+]], #0 381 ; MIPS32-LABEL: fcmpFalseFloat 382 ; MIPS32: addiu [[R:.*]], $zero, 0 383 ; MIPS32: andi [[R]], [[R]], 1 384 385 define internal i32 @fcmpFalseDouble(double %a, double %b) { 386 entry: 387 %cmp = fcmp false double %a, %b 388 %cmp.ret_ext = zext i1 %cmp to i32 389 ret i32 %cmp.ret_ext 390 } 391 ; CHECK-LABEL: fcmpFalseDouble 392 ; CHECK: mov {{.*}},0x0 393 ; ARM32-LABEL: fcmpFalseDouble 394 ; ARM32: mov [[R:r[0-9]+]], #0 395 ; MIPS32-LABEL: fcmpFalseDouble 396 ; MIPS32: addiu [[R:.*]], $zero, 0 397 ; MIPS32: andi [[R]], [[R]], 1 398 399 define internal i32 @fcmpOeqFloat(float %a, float %b) { 400 entry: 401 %cmp = fcmp oeq float %a, %b 402 %cmp.ret_ext = zext i1 %cmp to i32 403 ret i32 %cmp.ret_ext 404 } 405 ; CHECK-LABEL: fcmpOeqFloat 406 ; CHECK: ucomiss 407 ; CHECK: jne 408 ; CHECK: jp 409 ; ARM32-LABEL: fcmpOeqFloat 410 ; ARM32-O2: mov [[R:r[0-9]+]], #0 411 ; ARM32: vcmp.f32 412 ; ARM32: vmrs 413 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 414 ; ARM32: moveq [[R]], #1 415 ; MIPS32-LABEL: fcmpOeqFloat 416 ; MIPS32: c.eq.s 417 ; MIPS32: addiu [[REG:.*]], $zero, 1 418 ; MIPS32: movf [[REG]], $zero, {{.*}} 419 420 define internal i32 @fcmpOeqDouble(double %a, double %b) { 421 entry: 422 %cmp = fcmp oeq double %a, %b 423 %cmp.ret_ext = zext i1 %cmp to i32 424 ret i32 %cmp.ret_ext 425 } 426 ; CHECK-LABEL: fcmpOeqDouble 427 ; CHECK: ucomisd 428 ; CHECK: jne 429 ; CHECK: jp 430 ; ARM32-LABEL: fcmpOeqDouble 431 ; ARM32-O2: mov [[R:r[0-9]+]], #0 432 ; ARM32: vcmp.f64 433 ; ARM32: vmrs 434 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 435 ; ARM32: moveq [[R]], #1 436 ; MIPS32-LABEL: fcmpOeqDouble 437 ; MIPS32: c.eq.d 438 ; MIPS32: addiu [[REG:.*]], $zero, 1 439 ; MIPS32: movf [[REG]], $zero, {{.*}} 440 441 define internal i32 @fcmpOgtFloat(float %a, float %b) { 442 entry: 443 %cmp = fcmp ogt float %a, %b 444 %cmp.ret_ext = zext i1 %cmp to i32 445 ret i32 %cmp.ret_ext 446 } 447 ; CHECK-LABEL: fcmpOgtFloat 448 ; CHECK: ucomiss 449 ; CHECK: seta 450 ; ARM32-LABEL: fcmpOgtFloat 451 ; ARM32-O2: mov [[R:r[0-9]+]], #0 452 ; ARM32: vcmp.f32 453 ; ARM32: vmrs 454 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 455 ; ARM32: movgt [[R]], #1 456 ; MIPS32-LABEL: fcmpOgtFloat 457 ; MIPS32: c.ule.s 458 ; MIPS32: addiu [[REG:.*]], $zero, 1 459 ; MIPS32: movt [[REG]], $zero, {{.*}} 460 461 define internal i32 @fcmpOgtDouble(double %a, double %b) { 462 entry: 463 %cmp = fcmp ogt double %a, %b 464 %cmp.ret_ext = zext i1 %cmp to i32 465 ret i32 %cmp.ret_ext 466 } 467 ; CHECK-LABEL: fcmpOgtDouble 468 ; CHECK: ucomisd 469 ; CHECK: seta 470 ; ARM32-LABEL: fcmpOgtDouble 471 ; ARM32-O2: mov [[R:r[0-9]+]], #0 472 ; ARM32: vcmp.f64 473 ; ARM32: vmrs 474 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 475 ; ARM32: movgt [[R]], #1 476 ; MIPS32-LABEL: fcmpOgtDouble 477 ; MIPS32: c.ule.d 478 ; MIPS32: addiu [[REG:.*]], $zero, 1 479 ; MIPS32: movt [[REG]], $zero, {{.*}} 480 481 define internal i32 @fcmpOgeFloat(float %a, float %b) { 482 entry: 483 %cmp = fcmp oge float %a, %b 484 %cmp.ret_ext = zext i1 %cmp to i32 485 ret i32 %cmp.ret_ext 486 } 487 ; CHECK-LABEL: fcmpOgeFloat 488 ; CHECK: ucomiss 489 ; CHECK: setae 490 ; ARM32-LABEL: fcmpOgeFloat 491 ; ARM32-O2: mov [[R:r[0-9]+]], #0 492 ; ARM32: vcmp.f32 493 ; ARM32: vmrs 494 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 495 ; ARM32: movge [[R]], #1 496 ; MIPS32-LABEL: fcmpOgeFloat 497 ; MIPS32: c.ult.s 498 ; MIPS32: addiu [[REG:.*]], $zero, 1 499 ; MIPS32: movt [[REG]], $zero, {{.*}} 500 501 define internal i32 @fcmpOgeDouble(double %a, double %b) { 502 entry: 503 %cmp = fcmp oge double %a, %b 504 %cmp.ret_ext = zext i1 %cmp to i32 505 ret i32 %cmp.ret_ext 506 } 507 ; CHECK-LABEL: fcmpOgeDouble 508 ; CHECK: ucomisd 509 ; CHECK: setae 510 ; ARM32-LABEL: fcmpOgeDouble 511 ; ARM32-O2: mov [[R:r[0-9]+]], #0 512 ; ARM32: vcmp.f64 513 ; ARM32: vmrs 514 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 515 ; ARM32: movge [[R]], #1 516 ; MIPS32-LABEL: fcmpOgeDouble 517 ; MIPS32: c.ult.d 518 ; MIPS32: addiu [[REG:.*]], $zero, 1 519 ; MIPS32: movt [[REG]], $zero, {{.*}} 520 521 define internal i32 @fcmpOltFloat(float %a, float %b) { 522 entry: 523 %cmp = fcmp olt float %a, %b 524 %cmp.ret_ext = zext i1 %cmp to i32 525 ret i32 %cmp.ret_ext 526 } 527 ; CHECK-LABEL: fcmpOltFloat 528 ; CHECK: ucomiss 529 ; CHECK: seta 530 ; ARM32-LABEL: fcmpOltFloat 531 ; ARM32-O2: mov [[R:r[0-9]+]], #0 532 ; ARM32: vcmp.f32 533 ; ARM32: vmrs 534 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 535 ; ARM32: movmi [[R]], #1 536 ; MIPS32-LABEL: fcmpOltFloat 537 ; MIPS32: c.olt.s 538 ; MIPS32: addiu [[REG:.*]], $zero, 1 539 ; MIPS32: movf [[REG]], $zero, {{.*}} 540 541 define internal i32 @fcmpOltDouble(double %a, double %b) { 542 entry: 543 %cmp = fcmp olt double %a, %b 544 %cmp.ret_ext = zext i1 %cmp to i32 545 ret i32 %cmp.ret_ext 546 } 547 ; CHECK-LABEL: fcmpOltDouble 548 ; CHECK: ucomisd 549 ; CHECK: seta 550 ; ARM32-LABEL: fcmpOltDouble 551 ; ARM32-O2: mov [[R:r[0-9]+]], #0 552 ; ARM32: vcmp.f64 553 ; ARM32: vmrs 554 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 555 ; ARM32: movmi [[R]], #1 556 ; MIPS32-LABEL: fcmpOltDouble 557 ; MIPS32: c.olt.d 558 ; MIPS32: addiu [[REG:.*]], $zero, 1 559 ; MIPS32: movf [[REG]], $zero, {{.*}} 560 561 define internal i32 @fcmpOleFloat(float %a, float %b) { 562 entry: 563 %cmp = fcmp ole float %a, %b 564 %cmp.ret_ext = zext i1 %cmp to i32 565 ret i32 %cmp.ret_ext 566 } 567 ; CHECK-LABEL: fcmpOleFloat 568 ; CHECK: ucomiss 569 ; CHECK: setae 570 ; ARM32-LABEL: fcmpOleFloat 571 ; ARM32-O2: mov [[R:r[0-9]+]], #0 572 ; ARM32: vcmp.f32 573 ; ARM32: vmrs 574 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 575 ; ARM32: movls [[R]], #1 576 ; MIPS32-LABEL: fcmpOleFloat 577 ; MIPS32: c.ole.s 578 ; MIPS32: addiu [[REG:.*]], $zero, 1 579 ; MIPS32: movf [[REG]], $zero, {{.*}} 580 581 define internal i32 @fcmpOleDouble(double %a, double %b) { 582 entry: 583 %cmp = fcmp ole double %a, %b 584 %cmp.ret_ext = zext i1 %cmp to i32 585 ret i32 %cmp.ret_ext 586 } 587 ; CHECK-LABEL: fcmpOleDouble 588 ; CHECK: ucomisd 589 ; CHECK: setae 590 ; ARM32-LABEL: fcmpOleDouble 591 ; ARM32-O2: mov [[R:r[0-9]+]], #0 592 ; ARM32: vcmp.f64 593 ; ARM32: vmrs 594 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 595 ; ARM32: movls [[R]], #1 596 ; MIPS32-LABEL: fcmpOleDouble 597 ; MIPS32: c.ole.d 598 ; MIPS32: addiu [[REG:.*]], $zero, 1 599 ; MIPS32: movf [[REG]], $zero, {{.*}} 600 601 define internal i32 @fcmpOneFloat(float %a, float %b) { 602 entry: 603 %cmp = fcmp one float %a, %b 604 %cmp.ret_ext = zext i1 %cmp to i32 605 ret i32 %cmp.ret_ext 606 } 607 ; CHECK-LABEL: fcmpOneFloat 608 ; CHECK: ucomiss 609 ; CHECK: setne 610 ; ARM32-LABEL: fcmpOneFloat 611 ; ARM32-O2: mov [[R:r[0-9]+]], #0 612 ; ARM32: vcmp.f32 613 ; ARM32: vmrs 614 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 615 ; ARM32: movmi [[R]], #1 616 ; ARM32: movgt [[R]], #1 617 ; MIPS32-LABEL: fcmpOneFloat 618 ; MIPS32: c.ueq.s 619 ; MIPS32: addiu [[REG:.*]], $zero, 1 620 ; MIPS32: movt [[REG]], $zero, {{.*}} 621 622 define internal i32 @fcmpOneDouble(double %a, double %b) { 623 entry: 624 %cmp = fcmp one double %a, %b 625 %cmp.ret_ext = zext i1 %cmp to i32 626 ret i32 %cmp.ret_ext 627 } 628 ; CHECK-LABEL: fcmpOneDouble 629 ; CHECK: ucomisd 630 ; CHECK: setne 631 ; ARM32-LABEL: fcmpOneDouble 632 ; ARM32-O2: mov [[R:r[0-9]+]], #0 633 ; ARM32: vcmp.f64 634 ; ARM32: vmrs 635 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 636 ; ARM32: movmi [[R]], #1 637 ; ARM32: movgt [[R]], #1 638 ; MIPS32-LABEL: fcmpOneDouble 639 ; MIPS32: c.ueq.d 640 ; MIPS32: addiu [[REG:.*]], $zero, 1 641 ; MIPS32: movt [[REG]], $zero, {{.*}} 642 643 define internal i32 @fcmpOrdFloat(float %a, float %b) { 644 entry: 645 %cmp = fcmp ord float %a, %b 646 %cmp.ret_ext = zext i1 %cmp to i32 647 ret i32 %cmp.ret_ext 648 } 649 ; CHECK-LABEL: fcmpOrdFloat 650 ; CHECK: ucomiss 651 ; CHECK: setnp 652 ; ARM32-LABEL: fcmpOrdFloat 653 ; ARM32-O2: mov [[R:r[0-9]+]], #0 654 ; ARM32: vcmp.f32 655 ; ARM32: vmrs 656 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 657 ; ARM32: movvc [[R]], #1 658 ; MIPS32-LABEL: fcmpOrdFloat 659 ; MIPS32: c.un.s 660 ; MIPS32: addiu [[REG:.*]], $zero, 1 661 ; MIPS32: movt [[REG]], $zero, {{.*}} 662 663 define internal i32 @fcmpOrdDouble(double %a, double %b) { 664 entry: 665 %cmp = fcmp ord double %a, %b 666 %cmp.ret_ext = zext i1 %cmp to i32 667 ret i32 %cmp.ret_ext 668 } 669 ; CHECK-LABEL: fcmpOrdDouble 670 ; CHECK: ucomisd 671 ; CHECK: setnp 672 ; ARM32-LABEL: fcmpOrdDouble 673 ; ARM32-O2: mov [[R:r[0-9]+]], #0 674 ; ARM32: vcmp.f64 675 ; ARM32: vmrs 676 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 677 ; ARM32: movvc [[R]], #1 678 ; MIPS32-LABEL: fcmpOrdDouble 679 ; MIPS32: c.un.d 680 ; MIPS32: addiu [[REG:.*]], $zero, 1 681 ; MIPS32: movt [[REG]], $zero, {{.*}} 682 683 define internal i32 @fcmpUeqFloat(float %a, float %b) { 684 entry: 685 %cmp = fcmp ueq float %a, %b 686 %cmp.ret_ext = zext i1 %cmp to i32 687 ret i32 %cmp.ret_ext 688 } 689 ; CHECK-LABEL: fcmpUeqFloat 690 ; CHECK: ucomiss 691 ; CHECK: sete 692 ; ARM32-LABEL: fcmpUeqFloat 693 ; ARM32-O2: mov [[R:r[0-9]+]], #0 694 ; ARM32: vcmp.f32 695 ; ARM32: vmrs 696 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 697 ; ARM32: moveq [[R]], #1 698 ; ARM32: movvs [[R]], #1 699 ; MIPS32-LABEL: fcmpUeqFloat 700 ; MIPS32: c.ueq.s 701 ; MIPS32: addiu [[REG:.*]], $zero, 1 702 ; MIPS32: movf [[REG]], $zero, {{.*}} 703 704 define internal i32 @fcmpUeqDouble(double %a, double %b) { 705 entry: 706 %cmp = fcmp ueq double %a, %b 707 %cmp.ret_ext = zext i1 %cmp to i32 708 ret i32 %cmp.ret_ext 709 } 710 ; CHECK-LABEL: fcmpUeqDouble 711 ; CHECK: ucomisd 712 ; CHECK: sete 713 ; ARM32-LABEL: fcmpUeqDouble 714 ; ARM32-O2: mov [[R:r[0-9]+]], #0 715 ; ARM32: vcmp.f64 716 ; ARM32: vmrs 717 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 718 ; ARM32: moveq [[R]], #1 719 ; ARM32: movvs [[R]], #1 720 ; MIPS32-LABEL: fcmpUeqDouble 721 ; MIPS32: c.ueq.d 722 ; MIPS32: addiu [[REG:.*]], $zero, 1 723 ; MIPS32: movf [[REG]], $zero, {{.*}} 724 725 define internal i32 @fcmpUgtFloat(float %a, float %b) { 726 entry: 727 %cmp = fcmp ugt float %a, %b 728 %cmp.ret_ext = zext i1 %cmp to i32 729 ret i32 %cmp.ret_ext 730 } 731 ; CHECK-LABEL: fcmpUgtFloat 732 ; CHECK: ucomiss 733 ; CHECK: setb 734 ; ARM32-LABEL: fcmpUgtFloat 735 ; ARM32-O2: mov [[R:r[0-9]+]], #0 736 ; ARM32: vcmp.f32 737 ; ARM32: vmrs 738 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 739 ; ARM32: movhi [[R]], #1 740 ; MIPS32-LABEL: fcmpUgtFloat 741 ; MIPS32: c.ole.s 742 ; MIPS32: addiu [[REG:.*]], $zero, 1 743 ; MIPS32: movt [[REG]], $zero, {{.*}} 744 745 define internal i32 @fcmpUgtDouble(double %a, double %b) { 746 entry: 747 %cmp = fcmp ugt double %a, %b 748 %cmp.ret_ext = zext i1 %cmp to i32 749 ret i32 %cmp.ret_ext 750 } 751 ; CHECK-LABEL: fcmpUgtDouble 752 ; CHECK: ucomisd 753 ; CHECK: setb 754 ; ARM32-LABEL: fcmpUgtDouble 755 ; ARM32-O2: mov [[R:r[0-9]+]], #0 756 ; ARM32: vcmp.f64 757 ; ARM32: vmrs 758 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 759 ; ARM32: movhi [[R]], #1 760 ; MIPS32-LABEL: fcmpUgtDouble 761 ; MIPS32: c.ole.d 762 ; MIPS32: addiu [[REG:.*]], $zero, 1 763 ; MIPS32: movt [[REG]], $zero, {{.*}} 764 765 define internal i32 @fcmpUgeFloat(float %a, float %b) { 766 entry: 767 %cmp = fcmp uge float %a, %b 768 %cmp.ret_ext = zext i1 %cmp to i32 769 ret i32 %cmp.ret_ext 770 } 771 ; CHECK-LABEL: fcmpUgeFloat 772 ; CHECK: ucomiss 773 ; CHECK: setbe 774 ; ARM32-LABEL: fcmpUgeFloat 775 ; ARM32-O2: mov [[R:r[0-9]+]], #0 776 ; ARM32: vcmp.f32 777 ; ARM32: vmrs 778 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 779 ; ARM32: movpl [[R]], #1 780 ; MIPS32-LABEL: fcmpUgeFloat 781 ; MIPS32: c.olt.s 782 ; MIPS32: addiu [[REG:.*]], $zero, 1 783 ; MIPS32: movt [[REG]], $zero, {{.*}} 784 785 define internal i32 @fcmpUgeDouble(double %a, double %b) { 786 entry: 787 %cmp = fcmp uge double %a, %b 788 %cmp.ret_ext = zext i1 %cmp to i32 789 ret i32 %cmp.ret_ext 790 } 791 ; CHECK-LABEL: fcmpUgeDouble 792 ; CHECK: ucomisd 793 ; CHECK: setbe 794 ; ARM32-LABEL: fcmpUgeDouble 795 ; ARM32-O2: mov [[R:r[0-9]+]], #0 796 ; ARM32: vcmp.f64 797 ; ARM32: vmrs 798 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 799 ; ARM32: movpl [[R]], #1 800 ; MIPS32-LABEL: fcmpUgeDouble 801 ; MIPS32: c.olt.d 802 ; MIPS32: addiu [[REG:.*]], $zero, 1 803 ; MIPS32: movt [[REG]], $zero, {{.*}} 804 805 define internal i32 @fcmpUltFloat(float %a, float %b) { 806 entry: 807 %cmp = fcmp ult float %a, %b 808 %cmp.ret_ext = zext i1 %cmp to i32 809 ret i32 %cmp.ret_ext 810 } 811 ; CHECK-LABEL: fcmpUltFloat 812 ; CHECK: ucomiss 813 ; CHECK: setb 814 ; ARM32-LABEL: fcmpUltFloat 815 ; ARM32-O2: mov [[R:r[0-9]+]], #0 816 ; ARM32: vcmp.f32 817 ; ARM32: vmrs 818 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 819 ; ARM32: movlt [[R]], #1 820 ; MIPS32-LABEL: fcmpUltFloat 821 ; MIPS32: c.ult.s 822 ; MIPS32: addiu [[REG:.*]], $zero, 1 823 ; MIPS32: movf [[REG]], $zero, {{.*}} 824 825 define internal i32 @fcmpUltDouble(double %a, double %b) { 826 entry: 827 %cmp = fcmp ult double %a, %b 828 %cmp.ret_ext = zext i1 %cmp to i32 829 ret i32 %cmp.ret_ext 830 } 831 ; CHECK-LABEL: fcmpUltDouble 832 ; CHECK: ucomisd 833 ; CHECK: setb 834 ; ARM32-LABEL: fcmpUltDouble 835 ; ARM32-O2: mov [[R:r[0-9]+]], #0 836 ; ARM32: vcmp.f64 837 ; ARM32: vmrs 838 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 839 ; ARM32: movlt [[R]], #1 840 ; MIPS32-LABEL: fcmpUltDouble 841 ; MIPS32: c.ult.d 842 ; MIPS32: addiu [[REG:.*]], $zero, 1 843 ; MIPS32: movf [[REG]], $zero, {{.*}} 844 845 define internal i32 @fcmpUleFloat(float %a, float %b) { 846 entry: 847 %cmp = fcmp ule float %a, %b 848 %cmp.ret_ext = zext i1 %cmp to i32 849 ret i32 %cmp.ret_ext 850 } 851 ; CHECK-LABEL: fcmpUleFloat 852 ; CHECK: ucomiss 853 ; CHECK: setbe 854 ; ARM32-LABEL: fcmpUleFloat 855 ; ARM32-O2: mov [[R:r[0-9]+]], #0 856 ; ARM32: vcmp.f32 857 ; ARM32: vmrs 858 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 859 ; ARM32: movle [[R]], #1 860 ; MIPS32-LABEL: fcmpUleFloat 861 ; MIPS32: c.ule.s 862 ; MIPS32: addiu [[REG:.*]], $zero, 1 863 ; MIPS32: movf [[REG]], $zero, {{.*}} 864 865 define internal i32 @fcmpUleDouble(double %a, double %b) { 866 entry: 867 %cmp = fcmp ule double %a, %b 868 %cmp.ret_ext = zext i1 %cmp to i32 869 ret i32 %cmp.ret_ext 870 } 871 ; CHECK-LABEL: fcmpUleDouble 872 ; CHECK: ucomisd 873 ; CHECK: setbe 874 ; ARM32-LABEL: fcmpUleDouble 875 ; ARM32-O2: mov [[R:r[0-9]+]], #0 876 ; ARM32: vcmp.f64 877 ; ARM32: vmrs 878 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 879 ; ARM32: movle [[R]], #1 880 ; MIPS32-LABEL: fcmpUleDouble 881 ; MIPS32: c.ule.d 882 ; MIPS32: addiu [[REG:.*]], $zero, 1 883 ; MIPS32: movf [[REG]], $zero, {{.*}} 884 885 define internal i32 @fcmpUneFloat(float %a, float %b) { 886 entry: 887 %cmp = fcmp une float %a, %b 888 %cmp.ret_ext = zext i1 %cmp to i32 889 ret i32 %cmp.ret_ext 890 } 891 ; CHECK-LABEL: fcmpUneFloat 892 ; CHECK: ucomiss 893 ; CHECK: jne 894 ; CHECK: jp 895 ; ARM32-LABEL: fcmpUneFloat 896 ; ARM32-O2: mov [[R:r[0-9]+]], #0 897 ; ARM32: vcmp.f32 898 ; ARM32: vmrs 899 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 900 ; ARM32: movne [[R]], #1 901 ; MIPS32-LABEL: fcmpUneFloat 902 ; MIPS32: c.eq.s 903 ; MIPS32: addiu [[REG:.*]], $zero, 1 904 ; MIPS32: movt [[REG]], $zero, {{.*}} 905 906 define internal i32 @fcmpUneDouble(double %a, double %b) { 907 entry: 908 %cmp = fcmp une double %a, %b 909 %cmp.ret_ext = zext i1 %cmp to i32 910 ret i32 %cmp.ret_ext 911 } 912 ; CHECK-LABEL: fcmpUneDouble 913 ; CHECK: ucomisd 914 ; CHECK: jne 915 ; CHECK: jp 916 ; ARM32-LABEL: fcmpUneDouble 917 ; ARM32-O2: mov [[R:r[0-9]+]], #0 918 ; ARM32: vcmp.f64 919 ; ARM32: vmrs 920 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 921 ; ARM32: movne [[R]], #1 922 ; MIPS32-LABEL: fcmpUneDouble 923 ; MIPS32: c.eq.d 924 ; MIPS32: addiu [[REG:.*]], $zero, 1 925 ; MIPS32: movt [[REG]], $zero, {{.*}} 926 927 define internal i32 @fcmpUnoFloat(float %a, float %b) { 928 entry: 929 %cmp = fcmp uno float %a, %b 930 %cmp.ret_ext = zext i1 %cmp to i32 931 ret i32 %cmp.ret_ext 932 } 933 ; CHECK-LABEL: fcmpUnoFloat 934 ; CHECK: ucomiss 935 ; CHECK: setp 936 ; ARM32-LABEL: fcmpUnoFloat 937 ; ARM32-O2: mov [[R:r[0-9]+]], #0 938 ; ARM32: vcmp.f32 939 ; ARM32: vmrs 940 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 941 ; ARM32: movvs [[R]], #1 942 ; MIPS32-LABEL: fcmpUnoFloat 943 ; MIPS32: c.un.s 944 ; MIPS32: addiu [[REG:.*]], $zero, 1 945 ; MIPS32: movf [[REG]], $zero, {{.*}} 946 947 define internal i32 @fcmpUnoDouble(double %a, double %b) { 948 entry: 949 %cmp = fcmp uno double %a, %b 950 %cmp.ret_ext = zext i1 %cmp to i32 951 ret i32 %cmp.ret_ext 952 } 953 ; CHECK-LABEL: fcmpUnoDouble 954 ; CHECK: ucomisd 955 ; CHECK: setp 956 ; ARM32-LABEL: fcmpUnoDouble 957 ; ARM32-O2: mov [[R:r[0-9]+]], #0 958 ; ARM32: vcmp.f64 959 ; ARM32: vmrs 960 ; ARM32-OM1: mov [[R:r[0-9]+]], #0 961 ; ARM32: movvs [[R]], #1 962 ; MIPS32-LABEL: fcmpUnoDouble 963 ; MIPS32: c.un.d 964 ; MIPS32: addiu [[REG:.*]], $zero, 1 965 ; MIPS32: movf [[REG]], $zero, {{.*}} 966 967 define internal i32 @fcmpTrueFloat(float %a, float %b) { 968 entry: 969 %cmp = fcmp true float %a, %b 970 %cmp.ret_ext = zext i1 %cmp to i32 971 ret i32 %cmp.ret_ext 972 } 973 ; CHECK-LABEL: fcmpTrueFloat 974 ; CHECK: mov {{.*}},0x1 975 ; ARM32-LABEL: fcmpTrueFloat 976 ; ARM32: mov {{r[0-9]+}}, #1 977 ; MIPS32-LABEL: fcmpTrueFloat 978 ; MIPS32: addiu [[R:.*]], $zero, 1 979 ; MIPS32: andi [[R]], [[R]], 1 980 981 define internal i32 @fcmpTrueDouble(double %a, double %b) { 982 entry: 983 %cmp = fcmp true double %a, %b 984 %cmp.ret_ext = zext i1 %cmp to i32 985 ret i32 %cmp.ret_ext 986 } 987 ; CHECK-LABEL: fcmpTrueDouble 988 ; CHECK: mov {{.*}},0x1 989 ; ARM32-LABEL: fcmpTrueDouble 990 ; ARM32: mov {{r[0-9]+}}, #1 991 ; MIPS32-LABEL: fcmpTrueDouble 992 ; MIPS32: addiu [[R:.*]], $zero, 1 993 ; MIPS32: andi [[R]], [[R]], 1 994 995 define internal float @selectFloatVarVar(float %a, float %b) { 996 entry: 997 %cmp = fcmp olt float %a, %b 998 %cond = select i1 %cmp, float %a, float %b 999 ret float %cond 1000 } 1001 ; CHECK-LABEL: selectFloatVarVar 1002 ; CHECK: movss 1003 ; CHECK: minss 1004 ; ARM32-LABEL: selectFloatVarVar 1005 ; ARM32: vcmp.f32 1006 ; ARM32-OM1: vmovne.f32 s{{[0-9]+}} 1007 ; ARM32-O2: vmovmi.f32 s{{[0-9]+}} 1008 ; ARM32: bx 1009 ; MIPS32-LABEL: selectFloatVarVar 1010 ; MIPS32: movn.s {{.*}} 1011 1012 define internal double @selectDoubleVarVar(double %a, double %b) { 1013 entry: 1014 %cmp = fcmp olt double %a, %b 1015 %cond = select i1 %cmp, double %a, double %b 1016 ret double %cond 1017 } 1018 ; CHECK-LABEL: selectDoubleVarVar 1019 ; CHECK: movsd 1020 ; CHECK: minsd 1021 ; ARM32-LABEL: selectDoubleVarVar 1022 ; ARM32: vcmp.f64 1023 ; ARM32-OM1: vmovne.f64 d{{[0-9]+}} 1024 ; ARM32-O2: vmovmi.f64 d{{[0-9]+}} 1025 ; ARM32: bx 1026 ; MIPS32-LABEL: selectDoubleVarVar 1027 ; MIPS32: movn.d {{.*}} 1028