1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4; Infinity 5 6define i1 @inf0(double %arg) { 7; CHECK-LABEL: @inf0( 8; CHECK-NEXT: ret i1 false 9; 10 %tmp = fcmp ogt double %arg, 0x7FF0000000000000 11 ret i1 %tmp 12} 13 14define i1 @inf1(double %arg) { 15; CHECK-LABEL: @inf1( 16; CHECK-NEXT: ret i1 true 17; 18 %tmp = fcmp ule double %arg, 0x7FF0000000000000 19 ret i1 %tmp 20} 21 22; Negative infinity 23 24define i1 @ninf0(double %arg) { 25; CHECK-LABEL: @ninf0( 26; CHECK-NEXT: ret i1 false 27; 28 %tmp = fcmp olt double %arg, 0xFFF0000000000000 29 ret i1 %tmp 30} 31 32define i1 @ninf1(double %arg) { 33; CHECK-LABEL: @ninf1( 34; CHECK-NEXT: ret i1 true 35; 36 %tmp = fcmp uge double %arg, 0xFFF0000000000000 37 ret i1 %tmp 38} 39 40; NaNs 41 42define i1 @nan0(double %arg) { 43; CHECK-LABEL: @nan0( 44; CHECK-NEXT: ret i1 false 45; 46 %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF 47 ret i1 %tmp 48} 49 50define i1 @nan1(double %arg) { 51; CHECK-LABEL: @nan1( 52; CHECK-NEXT: ret i1 false 53; 54 %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF 55 ret i1 %tmp 56} 57 58define i1 @nan2(double %arg) { 59; CHECK-LABEL: @nan2( 60; CHECK-NEXT: ret i1 false 61; 62 %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF 63 ret i1 %tmp 64} 65 66define i1 @nan3(double %arg) { 67; CHECK-LABEL: @nan3( 68; CHECK-NEXT: ret i1 true 69; 70 %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF 71 ret i1 %tmp 72} 73 74define i1 @nan4(double %arg) { 75; CHECK-LABEL: @nan4( 76; CHECK-NEXT: ret i1 true 77; 78 %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF 79 ret i1 %tmp 80} 81 82define i1 @nan5(double %arg) { 83; CHECK-LABEL: @nan5( 84; CHECK-NEXT: ret i1 true 85; 86 %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF 87 ret i1 %tmp 88} 89 90; Negative NaN. 91 92define i1 @nnan0(double %arg) { 93; CHECK-LABEL: @nnan0( 94; CHECK-NEXT: ret i1 false 95; 96 %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF 97 ret i1 %tmp 98} 99 100define i1 @nnan1(double %arg) { 101; CHECK-LABEL: @nnan1( 102; CHECK-NEXT: ret i1 false 103; 104 %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF 105 ret i1 %tmp 106} 107 108define i1 @nnan2(double %arg) { 109; CHECK-LABEL: @nnan2( 110; CHECK-NEXT: ret i1 false 111; 112 %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF 113 ret i1 %tmp 114} 115 116define i1 @nnan3(double %arg) { 117; CHECK-LABEL: @nnan3( 118; CHECK-NEXT: ret i1 true 119; 120 %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF 121 ret i1 %tmp 122} 123 124define i1 @nnan4(double %arg) { 125; CHECK-LABEL: @nnan4( 126; CHECK-NEXT: ret i1 true 127; 128 %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF 129 ret i1 %tmp 130} 131 132define i1 @nnan5(double %arg) { 133; CHECK-LABEL: @nnan5( 134; CHECK-NEXT: ret i1 true 135; 136 %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF 137 ret i1 %tmp 138} 139 140; Negative zero. 141 142define i1 @nzero0() { 143; CHECK-LABEL: @nzero0( 144; CHECK-NEXT: ret i1 true 145; 146 %tmp = fcmp oeq double 0.0, -0.0 147 ret i1 %tmp 148} 149 150define i1 @nzero1() { 151; CHECK-LABEL: @nzero1( 152; CHECK-NEXT: ret i1 false 153; 154 %tmp = fcmp ogt double 0.0, -0.0 155 ret i1 %tmp 156} 157 158; No enlightenment here. 159 160define i1 @one_with_self(double %arg) { 161; CHECK-LABEL: @one_with_self( 162; CHECK-NEXT: ret i1 false 163; 164 %tmp = fcmp one double %arg, %arg 165 ret i1 %tmp 166} 167 168; These tests choose arbitrarily between float and double, 169; and between uge and olt, to give reasonble coverage 170; without combinatorial explosion. 171 172declare half @llvm.fabs.f16(half) 173declare float @llvm.fabs.f32(float) 174declare double @llvm.fabs.f64(double) 175declare <2 x float> @llvm.fabs.v2f32(<2 x float>) 176declare <3 x float> @llvm.fabs.v3f32(<3 x float>) 177declare <2 x double> @llvm.fabs.v2f64(<2 x double>) 178declare float @llvm.sqrt.f32(float) 179declare double @llvm.powi.f64(double,i32) 180declare float @llvm.exp.f32(float) 181declare float @llvm.minnum.f32(float, float) 182declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>) 183declare float @llvm.maxnum.f32(float, float) 184declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>) 185declare float @llvm.maximum.f32(float, float) 186declare double @llvm.exp2.f64(double) 187declare float @llvm.fma.f32(float,float,float) 188 189declare void @expect_equal(i1,i1) 190 191define i1 @orderedLessZeroTree(float,float,float,float) { 192; CHECK-LABEL: @orderedLessZeroTree( 193; CHECK-NEXT: ret i1 true 194; 195 %square = fmul float %0, %0 196 %abs = call float @llvm.fabs.f32(float %1) 197 %sqrt = call float @llvm.sqrt.f32(float %2) 198 %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt) 199 %div = fdiv float %square, %abs 200 %rem = frem float %sqrt, %fma 201 %add = fadd float %div, %rem 202 %uge = fcmp uge float %add, 0.000000e+00 203 ret i1 %uge 204} 205 206define i1 @orderedLessZero_fdiv(float %x) { 207; CHECK-LABEL: @orderedLessZero_fdiv( 208; CHECK-NEXT: ret i1 true 209; 210 %d = fdiv float %x, %x 211 %uge = fcmp uge float %d, 0.0 212 ret i1 %uge 213} 214 215; If x == -0.0, maxnum can return -0.0, but that still compares equal to 0.0. 216 217define i1 @orderedLessZero_maxnum(float %x) { 218; CHECK-LABEL: @orderedLessZero_maxnum( 219; CHECK-NEXT: ret i1 true 220; 221 %d = call float @llvm.maxnum.f32(float %x, float 0.0) 222 %uge = fcmp uge float %d, 0.0 223 ret i1 %uge 224} 225 226define i1 @orderedLessZeroExpExt(float) { 227; CHECK-LABEL: @orderedLessZeroExpExt( 228; CHECK-NEXT: ret i1 true 229; 230 %a = call float @llvm.exp.f32(float %0) 231 %b = fpext float %a to double 232 %uge = fcmp uge double %b, 0.000000e+00 233 ret i1 %uge 234} 235 236define i1 @orderedLessZeroExp2Trunc(double) { 237; CHECK-LABEL: @orderedLessZeroExp2Trunc( 238; CHECK-NEXT: ret i1 false 239; 240 %a = call double @llvm.exp2.f64(double %0) 241 %b = fptrunc double %a to float 242 %olt = fcmp olt float %b, 0.000000e+00 243 ret i1 %olt 244} 245 246define i1 @orderedLessZeroPowi(double,double) { 247; CHECK-LABEL: @orderedLessZeroPowi( 248; CHECK-NEXT: ret i1 false 249; 250 ; Even constant exponent 251 %a = call double @llvm.powi.f64(double %0, i32 2) 252 %square = fmul double %1, %1 253 ; Odd constant exponent with provably non-negative base 254 %b = call double @llvm.powi.f64(double %square, i32 3) 255 %c = fadd double %a, %b 256 %olt = fcmp olt double %b, 0.000000e+00 257 ret i1 %olt 258} 259 260define i1 @UIToFP_is_nan_or_positive_or_zero(i32 %x) { 261; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero( 262; CHECK-NEXT: ret i1 true 263; 264 %a = uitofp i32 %x to float 265 %r = fcmp uge float %a, 0.000000e+00 266 ret i1 %r 267} 268 269define <2 x i1> @UIToFP_is_nan_or_positive_or_zero_vec(<2 x i32> %x) { 270; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero_vec( 271; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 272; 273 %a = uitofp <2 x i32> %x to <2 x float> 274 %r = fcmp uge <2 x float> %a, zeroinitializer 275 ret <2 x i1> %r 276} 277 278define i1 @UIToFP_is_positive_or_zero(i32 %x) { 279; CHECK-LABEL: @UIToFP_is_positive_or_zero( 280; CHECK-NEXT: ret i1 true 281; 282 %a = uitofp i32 %x to float 283 %r = fcmp oge float %a, 0.000000e+00 284 ret i1 %r 285} 286 287define <2 x i1> @UIToFP_is_positive_or_zero_vec(<2 x i32> %x) { 288; CHECK-LABEL: @UIToFP_is_positive_or_zero_vec( 289; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 290; 291 %a = uitofp <2 x i32> %x to <2 x float> 292 %r = fcmp oge <2 x float> %a, zeroinitializer 293 ret <2 x i1> %r 294} 295 296define i1 @UIToFP_nnan_is_positive_or_zero(i32 %x) { 297; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero( 298; CHECK-NEXT: ret i1 true 299; 300 %a = uitofp i32 %x to float 301 %r = fcmp nnan oge float %a, 0.000000e+00 302 ret i1 %r 303} 304 305define <2 x i1> @UIToFP_nnan_is_positive_or_zero_vec(<2 x i32> %x) { 306; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero_vec( 307; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 308; 309 %a = uitofp <2 x i32> %x to <2 x float> 310 %r = fcmp nnan oge <2 x float> %a, zeroinitializer 311 ret <2 x i1> %r 312} 313 314define i1 @UIToFP_is_not_negative(i32 %x) { 315; CHECK-LABEL: @UIToFP_is_not_negative( 316; CHECK-NEXT: ret i1 false 317; 318 %a = uitofp i32 %x to float 319 %r = fcmp olt float %a, 0.000000e+00 320 ret i1 %r 321} 322 323define <2 x i1> @UIToFP_is_not_negative_vec(<2 x i32> %x) { 324; CHECK-LABEL: @UIToFP_is_not_negative_vec( 325; CHECK-NEXT: ret <2 x i1> zeroinitializer 326; 327 %a = uitofp <2 x i32> %x to <2 x float> 328 %r = fcmp olt <2 x float> %a, zeroinitializer 329 ret <2 x i1> %r 330} 331 332; No FMF are required for this transform. 333 334define i1 @UIToFP_is_not_negative_or_nan(i32 %x) { 335; CHECK-LABEL: @UIToFP_is_not_negative_or_nan( 336; CHECK-NEXT: ret i1 false 337; 338 %a = uitofp i32 %x to float 339 %r = fcmp ult float %a, 0.000000e+00 340 ret i1 %r 341} 342 343define <2 x i1> @UIToFP_is_not_negative_or_nan_vec(<2 x i32> %x) { 344; CHECK-LABEL: @UIToFP_is_not_negative_or_nan_vec( 345; CHECK-NEXT: ret <2 x i1> zeroinitializer 346; 347 %a = uitofp <2 x i32> %x to <2 x float> 348 %r = fcmp ult <2 x float> %a, zeroinitializer 349 ret <2 x i1> %r 350} 351 352define i1 @UIToFP_nnan_is_not_negative(i32 %x) { 353; CHECK-LABEL: @UIToFP_nnan_is_not_negative( 354; CHECK-NEXT: ret i1 false 355; 356 %a = uitofp i32 %x to float 357 %r = fcmp nnan ult float %a, 0.000000e+00 358 ret i1 %r 359} 360 361define <2 x i1> @UIToFP_nnan_is_not_negative_vec(<2 x i32> %x) { 362; CHECK-LABEL: @UIToFP_nnan_is_not_negative_vec( 363; CHECK-NEXT: ret <2 x i1> zeroinitializer 364; 365 %a = uitofp <2 x i32> %x to <2 x float> 366 %r = fcmp nnan ult <2 x float> %a, zeroinitializer 367 ret <2 x i1> %r 368} 369 370define i1 @fabs_is_nan_or_positive_or_zero(double %x) { 371; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero( 372; CHECK-NEXT: ret i1 true 373; 374 %fabs = tail call double @llvm.fabs.f64(double %x) 375 %cmp = fcmp uge double %fabs, 0.0 376 ret i1 %cmp 377} 378 379define <2 x i1> @fabs_is_nan_or_positive_or_zero_vec(<2 x double> %x) { 380; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero_vec( 381; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 382; 383 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 384 %cmp = fcmp uge <2 x double> %fabs, zeroinitializer 385 ret <2 x i1> %cmp 386} 387 388define i1 @fabs_nnan_is_positive_or_zero(double %x) { 389; CHECK-LABEL: @fabs_nnan_is_positive_or_zero( 390; CHECK-NEXT: ret i1 true 391; 392 %fabs = tail call nnan double @llvm.fabs.f64(double %x) 393 %cmp = fcmp oge double %fabs, 0.0 394 ret i1 %cmp 395} 396 397define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) { 398; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec( 399; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 400; 401 %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 402 %cmp = fcmp oge <2 x double> %fabs, zeroinitializer 403 ret <2 x i1> %cmp 404} 405 406define i1 @fabs_fcmp-nnan_is_positive_or_zero(double %x) { 407; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero( 408; CHECK-NEXT: ret i1 true 409; 410 %fabs = tail call double @llvm.fabs.f64(double %x) 411 %cmp = fcmp nnan oge double %fabs, 0.0 412 ret i1 %cmp 413} 414 415define <2 x i1> @fabs_fcmp-nnan_is_positive_or_zero_vec(<2 x double> %x) { 416; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero_vec( 417; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 418; 419 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 420 %cmp = fcmp nnan oge <2 x double> %fabs, zeroinitializer 421 ret <2 x i1> %cmp 422} 423 424define i1 @fabs_is_not_negative(double %x) { 425; CHECK-LABEL: @fabs_is_not_negative( 426; CHECK-NEXT: ret i1 false 427; 428 %fabs = tail call double @llvm.fabs.f64(double %x) 429 %cmp = fcmp olt double %fabs, 0.0 430 ret i1 %cmp 431} 432 433define <2 x i1> @fabs_is_not_negative_vec(<2 x double> %x) { 434; CHECK-LABEL: @fabs_is_not_negative_vec( 435; CHECK-NEXT: ret <2 x i1> zeroinitializer 436; 437 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 438 %cmp = fcmp olt <2 x double> %fabs, zeroinitializer 439 ret <2 x i1> %cmp 440} 441 442define i1 @fabs_nnan_is_not_negative(double %x) { 443; CHECK-LABEL: @fabs_nnan_is_not_negative( 444; CHECK-NEXT: ret i1 false 445; 446 %fabs = tail call nnan double @llvm.fabs.f64(double %x) 447 %cmp = fcmp ult double %fabs, 0.0 448 ret i1 %cmp 449} 450 451define <2 x i1> @fabs_nnan_is_not_negative_vec(<2 x double> %x) { 452; CHECK-LABEL: @fabs_nnan_is_not_negative_vec( 453; CHECK-NEXT: ret <2 x i1> zeroinitializer 454; 455 %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 456 %cmp = fcmp ult <2 x double> %fabs, zeroinitializer 457 ret <2 x i1> %cmp 458} 459 460define i1 @fabs_fcmp-nnan_is_not_negative(double %x) { 461; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative( 462; CHECK-NEXT: ret i1 false 463; 464 %fabs = tail call double @llvm.fabs.f64(double %x) 465 %cmp = fcmp nnan ult double %fabs, 0.0 466 ret i1 %cmp 467} 468 469define <2 x i1> @fabs_fcmp-nnan_is_not_negative_vec(<2 x double> %x) { 470; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative_vec( 471; CHECK-NEXT: ret <2 x i1> zeroinitializer 472; 473 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 474 %cmp = fcmp nnan ult <2 x double> %fabs, zeroinitializer 475 ret <2 x i1> %cmp 476} 477 478define <2 x i1> @fabs_is_not_negative_negzero(<2 x float> %V) { 479; CHECK-LABEL: @fabs_is_not_negative_negzero( 480; CHECK-NEXT: ret <2 x i1> zeroinitializer 481; 482 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 483 %cmp = fcmp olt <2 x float> %abs, <float -0.0, float -0.0> 484 ret <2 x i1> %cmp 485} 486 487define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) { 488; CHECK-LABEL: @fabs_is_not_negative_poszero( 489; CHECK-NEXT: ret <2 x i1> zeroinitializer 490; 491 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 492 %cmp = fcmp olt <2 x float> %abs, <float 0.0, float 0.0> 493 ret <2 x i1> %cmp 494} 495 496define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) { 497; CHECK-LABEL: @fabs_is_not_negative_anyzero( 498; CHECK-NEXT: ret <2 x i1> zeroinitializer 499; 500 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 501 %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0> 502 ret <2 x i1> %cmp 503} 504 505define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) { 506; CHECK-LABEL: @fabs_is_not_negative_negzero_undef( 507; CHECK-NEXT: ret <3 x i1> zeroinitializer 508; 509 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 510 %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float undef> 511 ret <3 x i1> %cmp 512} 513 514define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) { 515; CHECK-LABEL: @fabs_is_not_negative_poszero_undef( 516; CHECK-NEXT: ret <3 x i1> zeroinitializer 517; 518 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 519 %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float undef> 520 ret <3 x i1> %cmp 521} 522 523define <3 x i1> @fabs_is_not_negative_anyzero_undef(<3 x float> %V) { 524; CHECK-LABEL: @fabs_is_not_negative_anyzero_undef( 525; CHECK-NEXT: ret <3 x i1> zeroinitializer 526; 527 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 528 %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float undef> 529 ret <3 x i1> %cmp 530} 531 532define i1 @orderedLessZeroSelect(float, float) { 533; CHECK-LABEL: @orderedLessZeroSelect( 534; CHECK-NEXT: ret i1 true 535; 536 %a = call float @llvm.exp.f32(float %0) 537 %b = call float @llvm.fabs.f32(float %1) 538 %c = fcmp olt float %0, %1 539 %d = select i1 %c, float %a, float %b 540 %e = fadd float %d, 1.0 541 %uge = fcmp uge float %e, 0.000000e+00 542 ret i1 %uge 543} 544 545define i1 @orderedLessZeroMinNum(float, float) { 546; CHECK-LABEL: @orderedLessZeroMinNum( 547; CHECK-NEXT: ret i1 true 548; 549 %a = call float @llvm.exp.f32(float %0) 550 %b = call float @llvm.fabs.f32(float %1) 551 %c = call float @llvm.minnum.f32(float %a, float %b) 552 %uge = fcmp uge float %c, 0.000000e+00 553 ret i1 %uge 554} 555 556; PR37776: https://bugs.llvm.org/show_bug.cgi?id=37776 557; exp() may return nan, leaving %1 as the unknown result, so we can't simplify. 558 559define i1 @orderedLessZeroMaxNum(float, float) { 560; CHECK-LABEL: @orderedLessZeroMaxNum( 561; CHECK-NEXT: [[A:%.*]] = call float @llvm.exp.f32(float [[TMP0:%.*]]) 562; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[TMP1:%.*]]) 563; CHECK-NEXT: [[UGE:%.*]] = fcmp uge float [[B]], 0.000000e+00 564; CHECK-NEXT: ret i1 [[UGE]] 565; 566 %a = call float @llvm.exp.f32(float %0) 567 %b = call float @llvm.maxnum.f32(float %a, float %1) 568 %uge = fcmp uge float %b, 0.000000e+00 569 ret i1 %uge 570} 571 572; But using maximum, we can simplify, since the NaN would be propagated 573 574define i1 @orderedLessZeroMaximum(float, float) { 575; CHECK-LABEL: @orderedLessZeroMaximum( 576; CHECK-NEXT: ret i1 true 577; 578 %a = call float @llvm.exp.f32(float %0) 579 %b = call float @llvm.maximum.f32(float %a, float %1) 580 %uge = fcmp uge float %b, 0.000000e+00 581 ret i1 %uge 582} 583 584define i1 @minnum_non_nan(float %x) { 585; CHECK-LABEL: @minnum_non_nan( 586; CHECK-NEXT: ret i1 true 587; 588 %min = call float @llvm.minnum.f32(float 0.5, float %x) 589 %cmp = fcmp ord float %min, 1.0 590 ret i1 %cmp 591} 592 593define i1 @maxnum_non_nan(float %x) { 594; CHECK-LABEL: @maxnum_non_nan( 595; CHECK-NEXT: ret i1 false 596; 597 %min = call float @llvm.maxnum.f32(float %x, float 42.0) 598 %cmp = fcmp uno float %min, 12.0 599 ret i1 %cmp 600} 601 602; min(x, 0.5) == 1.0 --> false 603 604define i1 @minnum_oeq_small_min_constant(float %x) { 605; CHECK-LABEL: @minnum_oeq_small_min_constant( 606; CHECK-NEXT: ret i1 false 607; 608 %min = call float @llvm.minnum.f32(float %x, float 0.5) 609 %cmp = fcmp oeq float %min, 1.0 610 ret i1 %cmp 611} 612 613; min(x, 0.5) > 1.0 --> false 614 615define i1 @minnum_ogt_small_min_constant(float %x) { 616; CHECK-LABEL: @minnum_ogt_small_min_constant( 617; CHECK-NEXT: ret i1 false 618; 619 %min = call float @llvm.minnum.f32(float %x, float 0.5) 620 %cmp = fcmp ogt float %min, 1.0 621 ret i1 %cmp 622} 623 624; min(x, 0.5) >= 1.0 --> false 625 626define i1 @minnum_oge_small_min_constant(float %x) { 627; CHECK-LABEL: @minnum_oge_small_min_constant( 628; CHECK-NEXT: ret i1 false 629; 630 %min = call float @llvm.minnum.f32(float %x, float 0.5) 631 %cmp = fcmp oge float %min, 1.0 632 ret i1 %cmp 633} 634 635; min(x, 0.5) == 1.0 --> false 636 637define i1 @minnum_ueq_small_min_constant(float %x) { 638; CHECK-LABEL: @minnum_ueq_small_min_constant( 639; CHECK-NEXT: ret i1 false 640; 641 %min = call float @llvm.minnum.f32(float %x, float 0.5) 642 %cmp = fcmp ueq float %min, 1.0 643 ret i1 %cmp 644} 645 646; min(x, 0.5) > 1.0 --> false 647 648define i1 @minnum_ugt_small_min_constant(float %x) { 649; CHECK-LABEL: @minnum_ugt_small_min_constant( 650; CHECK-NEXT: ret i1 false 651; 652 %min = call float @llvm.minnum.f32(float %x, float 0.5) 653 %cmp = fcmp ugt float %min, 1.0 654 ret i1 %cmp 655} 656 657; min(x, 0.5) >= 1.0 --> false 658 659define <2 x i1> @minnum_uge_small_min_constant(<2 x float> %x) { 660; CHECK-LABEL: @minnum_uge_small_min_constant( 661; CHECK-NEXT: ret <2 x i1> zeroinitializer 662; 663 %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>) 664 %cmp = fcmp uge <2 x float> %min, <float 1.0, float 1.0> 665 ret <2 x i1> %cmp 666} 667 668; min(x, 0.5) < 1.0 --> true 669 670define <2 x i1> @minnum_olt_small_min_constant(<2 x float> %x) { 671; CHECK-LABEL: @minnum_olt_small_min_constant( 672; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 673; 674 %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>) 675 %cmp = fcmp olt <2 x float> %min, <float 1.0, float 1.0> 676 ret <2 x i1> %cmp 677} 678 679; min(x, 0.5) <= 1.0 --> true 680 681define i1 @minnum_ole_small_min_constant(float %x) { 682; CHECK-LABEL: @minnum_ole_small_min_constant( 683; CHECK-NEXT: ret i1 true 684; 685 %min = call float @llvm.minnum.f32(float %x, float 0.5) 686 %cmp = fcmp ole float %min, 1.0 687 ret i1 %cmp 688} 689 690; min(x, 0.5) != 1.0 --> true 691 692define i1 @minnum_one_small_min_constant(float %x) { 693; CHECK-LABEL: @minnum_one_small_min_constant( 694; CHECK-NEXT: ret i1 true 695; 696 %min = call float @llvm.minnum.f32(float %x, float 0.5) 697 %cmp = fcmp one float %min, 1.0 698 ret i1 %cmp 699} 700 701; min(x, 0.5) < 1.0 --> true 702 703define i1 @minnum_ult_small_min_constant(float %x) { 704; CHECK-LABEL: @minnum_ult_small_min_constant( 705; CHECK-NEXT: ret i1 true 706; 707 %min = call float @llvm.minnum.f32(float %x, float 0.5) 708 %cmp = fcmp ult float %min, 1.0 709 ret i1 %cmp 710} 711 712; min(x, 0.5) <= 1.0 --> true 713 714define i1 @minnum_ule_small_min_constant(float %x) { 715; CHECK-LABEL: @minnum_ule_small_min_constant( 716; CHECK-NEXT: ret i1 true 717; 718 %min = call float @llvm.minnum.f32(float %x, float 0.5) 719 %cmp = fcmp ule float %min, 1.0 720 ret i1 %cmp 721} 722 723; min(x, 0.5) != 1.0 --> true 724 725define i1 @minnum_une_small_min_constant(float %x) { 726; CHECK-LABEL: @minnum_une_small_min_constant( 727; CHECK-NEXT: ret i1 true 728; 729 %min = call float @llvm.minnum.f32(float %x, float 0.5) 730 %cmp = fcmp une float %min, 1.0 731 ret i1 %cmp 732} 733 734; Negative test: 735; min(x, 1.0) != 1.0 --> ? 736 737define i1 @minnum_une_equal_min_constant(float %x) { 738; CHECK-LABEL: @minnum_une_equal_min_constant( 739; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00) 740; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00 741; CHECK-NEXT: ret i1 [[CMP]] 742; 743 %min = call float @llvm.minnum.f32(float %x, float 1.0) 744 %cmp = fcmp une float %min, 1.0 745 ret i1 %cmp 746} 747 748; Negative test: 749; min(x, 2.0) != 1.0 --> ? 750 751define i1 @minnum_une_large_min_constant(float %x) { 752; CHECK-LABEL: @minnum_une_large_min_constant( 753; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.000000e+00) 754; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00 755; CHECK-NEXT: ret i1 [[CMP]] 756; 757 %min = call float @llvm.minnum.f32(float %x, float 2.0) 758 %cmp = fcmp une float %min, 1.0 759 ret i1 %cmp 760} 761 762; Partial negative test (the minnum simplifies): 763; min(x, NaN) != 1.0 --> x != 1.0 764 765define i1 @minnum_une_nan_min_constant(float %x) { 766; CHECK-LABEL: @minnum_une_nan_min_constant( 767; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00 768; CHECK-NEXT: ret i1 [[CMP]] 769; 770 %min = call float @llvm.minnum.f32(float %x, float 0x7FF8000000000000) 771 %cmp = fcmp une float %min, 1.0 772 ret i1 %cmp 773} 774 775; max(x, 1.5) == 1.0 --> false 776 777define i1 @maxnum_oeq_large_max_constant(float %x) { 778; CHECK-LABEL: @maxnum_oeq_large_max_constant( 779; CHECK-NEXT: ret i1 false 780; 781 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 782 %cmp = fcmp oeq float %max, 1.0 783 ret i1 %cmp 784} 785 786; max(x, 1.5) < 1.0 --> false 787 788define i1 @maxnum_olt_large_max_constant(float %x) { 789; CHECK-LABEL: @maxnum_olt_large_max_constant( 790; CHECK-NEXT: ret i1 false 791; 792 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 793 %cmp = fcmp olt float %max, 1.0 794 ret i1 %cmp 795} 796 797; max(x, 1.5) <= 1.0 --> false 798 799define i1 @maxnum_ole_large_max_constant(float %x) { 800; CHECK-LABEL: @maxnum_ole_large_max_constant( 801; CHECK-NEXT: ret i1 false 802; 803 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 804 %cmp = fcmp ole float %max, 1.0 805 ret i1 %cmp 806} 807 808; max(x, 1.5) == 1.0 --> false 809 810define i1 @maxnum_ueq_large_max_constant(float %x) { 811; CHECK-LABEL: @maxnum_ueq_large_max_constant( 812; CHECK-NEXT: ret i1 false 813; 814 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 815 %cmp = fcmp ueq float %max, 1.0 816 ret i1 %cmp 817} 818 819; max(x, 1.5) < 1.0 --> false 820 821define i1 @maxnum_ult_large_max_constant(float %x) { 822; CHECK-LABEL: @maxnum_ult_large_max_constant( 823; CHECK-NEXT: ret i1 false 824; 825 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 826 %cmp = fcmp ult float %max, 1.0 827 ret i1 %cmp 828} 829 830; max(x, 1.5) <= 1.0 --> false 831 832define <2 x i1> @maxnum_ule_large_max_constant(<2 x float> %x) { 833; CHECK-LABEL: @maxnum_ule_large_max_constant( 834; CHECK-NEXT: ret <2 x i1> zeroinitializer 835; 836 %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>) 837 %cmp = fcmp ule <2 x float> %max, <float 1.0, float 1.0> 838 ret <2 x i1> %cmp 839} 840 841; max(x, 1.5) > 1.0 --> true 842 843define <2 x i1> @maxnum_ogt_large_max_constant(<2 x float> %x) { 844; CHECK-LABEL: @maxnum_ogt_large_max_constant( 845; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 846; 847 %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>) 848 %cmp = fcmp ogt <2 x float> %max, <float 1.0, float 1.0> 849 ret <2 x i1> %cmp 850} 851 852; max(x, 1.5) >= 1.0 --> true 853 854define i1 @maxnum_oge_large_max_constant(float %x) { 855; CHECK-LABEL: @maxnum_oge_large_max_constant( 856; CHECK-NEXT: ret i1 true 857; 858 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 859 %cmp = fcmp oge float %max, 1.0 860 ret i1 %cmp 861} 862 863; max(x, 1.5) != 1.0 --> true 864 865define i1 @maxnum_one_large_max_constant(float %x) { 866; CHECK-LABEL: @maxnum_one_large_max_constant( 867; CHECK-NEXT: ret i1 true 868; 869 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 870 %cmp = fcmp one float %max, 1.0 871 ret i1 %cmp 872} 873 874; max(x, 1.5) > 1.0 --> true 875 876define i1 @maxnum_ugt_large_max_constant(float %x) { 877; CHECK-LABEL: @maxnum_ugt_large_max_constant( 878; CHECK-NEXT: ret i1 true 879; 880 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 881 %cmp = fcmp ugt float %max, 1.0 882 ret i1 %cmp 883} 884 885; max(x, 1.5) >= 1.0 --> true 886 887define i1 @maxnum_uge_large_max_constant(float %x) { 888; CHECK-LABEL: @maxnum_uge_large_max_constant( 889; CHECK-NEXT: ret i1 true 890; 891 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 892 %cmp = fcmp uge float %max, 1.0 893 ret i1 %cmp 894} 895 896; max(x, 1.5) != 1.0 --> true 897 898define i1 @maxnum_une_large_max_constant(float %x) { 899; CHECK-LABEL: @maxnum_une_large_max_constant( 900; CHECK-NEXT: ret i1 true 901; 902 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 903 %cmp = fcmp une float %max, 1.0 904 ret i1 %cmp 905} 906 907; Negative test: 908; max(x, 1.0) != 1.0 --> ? 909 910define i1 @maxnum_une_equal_max_constant(float %x) { 911; CHECK-LABEL: @maxnum_une_equal_max_constant( 912; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00) 913; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00 914; CHECK-NEXT: ret i1 [[CMP]] 915; 916 %max = call float @llvm.maxnum.f32(float %x, float 1.0) 917 %cmp = fcmp une float %max, 1.0 918 ret i1 %cmp 919} 920 921; Negative test: 922; max(x, 0.5) != 1.0 --> ? 923 924define i1 @maxnum_une_small_max_constant(float %x) { 925; CHECK-LABEL: @maxnum_une_small_max_constant( 926; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 5.000000e-01) 927; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00 928; CHECK-NEXT: ret i1 [[CMP]] 929; 930 %max = call float @llvm.maxnum.f32(float %x, float 0.5) 931 %cmp = fcmp une float %max, 1.0 932 ret i1 %cmp 933} 934 935; Partial negative test (the maxnum simplifies): 936; max(x, NaN) != 1.0 --> x != 1.0 937 938define i1 @maxnum_une_nan_max_constant(float %x) { 939; CHECK-LABEL: @maxnum_une_nan_max_constant( 940; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00 941; CHECK-NEXT: ret i1 [[CMP]] 942; 943 %max = call float @llvm.maxnum.f32(float %x, float 0x7FF8000000000000) 944 %cmp = fcmp une float %max, 1.0 945 ret i1 %cmp 946} 947 948define i1 @known_positive_olt_with_negative_constant(double %a) { 949; CHECK-LABEL: @known_positive_olt_with_negative_constant( 950; CHECK-NEXT: ret i1 false 951; 952 %call = call double @llvm.fabs.f64(double %a) 953 %cmp = fcmp olt double %call, -1.0 954 ret i1 %cmp 955} 956 957define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) { 958; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec( 959; CHECK-NEXT: ret <2 x i1> zeroinitializer 960; 961 %call = uitofp <2 x i32> %a to <2 x double> 962 %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0> 963 ret <2 x i1> %cmp 964} 965 966define i1 @known_positive_ugt_with_negative_constant(i32 %a) { 967; CHECK-LABEL: @known_positive_ugt_with_negative_constant( 968; CHECK-NEXT: ret i1 true 969; 970 %call = uitofp i32 %a to float 971 %cmp = fcmp ugt float %call, -3.0 972 ret i1 %cmp 973} 974 975define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) { 976; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec( 977; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 978; 979 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 980 %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0> 981 ret <2 x i1> %cmp 982} 983 984define i1 @known_positive_oeq_with_negative_constant(half %a) { 985; CHECK-LABEL: @known_positive_oeq_with_negative_constant( 986; CHECK-NEXT: ret i1 false 987; 988 %call = call half @llvm.fabs.f16(half %a) 989 %cmp = fcmp oeq half %call, -5.0 990 ret i1 %cmp 991} 992 993define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) { 994; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec( 995; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 996; 997 %call = uitofp <2 x i32> %a to <2 x half> 998 %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0> 999 ret <2 x i1> %cmp 1000} 1001 1002define i1 @nonans1(double %in1, double %in2) { 1003; CHECK-LABEL: @nonans1( 1004; CHECK-NEXT: ret i1 false 1005; 1006 %cmp = fcmp nnan uno double %in1, %in2 1007 ret i1 %cmp 1008} 1009 1010define i1 @nonans2(double %in1, double %in2) { 1011; CHECK-LABEL: @nonans2( 1012; CHECK-NEXT: ret i1 true 1013; 1014 %cmp = fcmp nnan ord double %in1, %in2 1015 ret i1 %cmp 1016} 1017 1018define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) { 1019; CHECK-LABEL: @orderedCompareWithNaNVector( 1020; CHECK-NEXT: ret <2 x i1> zeroinitializer 1021; 1022 %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF> 1023 ret <2 x i1> %cmp 1024} 1025 1026define <2 x i1> @orderedCompareWithNaNVector_undef_elt(<2 x double> %A) { 1027; CHECK-LABEL: @orderedCompareWithNaNVector_undef_elt( 1028; CHECK-NEXT: ret <2 x i1> zeroinitializer 1029; 1030 %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double undef> 1031 ret <2 x i1> %cmp 1032} 1033 1034define <2 x i1> @unorderedCompareWithNaNVector_undef_elt(<2 x double> %A) { 1035; CHECK-LABEL: @unorderedCompareWithNaNVector_undef_elt( 1036; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 1037; 1038 %cmp = fcmp ult <2 x double> %A, <double undef, double 0xFFFFFFFFFFFFFFFF> 1039 ret <2 x i1> %cmp 1040} 1041 1042define i1 @is_infinite(float %x) { 1043; CHECK-LABEL: @is_infinite( 1044; CHECK-NEXT: ret i1 false 1045; 1046 %xabs = call ninf float @llvm.fabs.f32(float %x) 1047 %r = fcmp oeq float %xabs, 0x7FF0000000000000 1048 ret i1 %r 1049} 1050 1051define <2 x i1> @is_infinite_neg(<2 x float> %x) { 1052; CHECK-LABEL: @is_infinite_neg( 1053; CHECK-NEXT: ret <2 x i1> zeroinitializer 1054; 1055 %x42 = fadd ninf <2 x float> %x, <float 42.0, float 42.0> 1056 %r = fcmp oeq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000> 1057 ret <2 x i1> %r 1058} 1059 1060; Negative test - but this could be reduced to 'uno' outside of instsimplify. 1061 1062define i1 @is_infinite_or_nan(float %x) { 1063; CHECK-LABEL: @is_infinite_or_nan( 1064; CHECK-NEXT: [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01 1065; CHECK-NEXT: [[R:%.*]] = fcmp ueq float [[X42]], 0xFFF0000000000000 1066; CHECK-NEXT: ret i1 [[R]] 1067; 1068 %x42 = fadd ninf float %x, 42.0 1069 %r = fcmp ueq float %x42, 0xFFF0000000000000 1070 ret i1 %r 1071} 1072 1073define i1 @is_infinite_or_nan2(float %x) { 1074; CHECK-LABEL: @is_infinite_or_nan2( 1075; CHECK-NEXT: ret i1 false 1076; 1077 %xabs = call nnan ninf float @llvm.fabs.f32(float %x) 1078 %r = fcmp ueq float %xabs, 0x7FF0000000000000 1079 ret i1 %r 1080} 1081 1082define <2 x i1> @is_infinite_neg_or_nan(<2 x float> %x) { 1083; CHECK-LABEL: @is_infinite_neg_or_nan( 1084; CHECK-NEXT: ret <2 x i1> zeroinitializer 1085; 1086 %x42 = fadd nnan ninf <2 x float> %x, <float 42.0, float 42.0> 1087 %r = fcmp ueq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000> 1088 ret <2 x i1> %r 1089} 1090 1091define i1 @is_finite_or_nan(i1 %c, double %x) { 1092; CHECK-LABEL: @is_finite_or_nan( 1093; CHECK-NEXT: ret i1 true 1094; 1095 %xx = fmul ninf double %x, %x 1096 %s = select i1 %c, double 42.0, double %xx 1097 %r = fcmp une double %s, 0x7FF0000000000000 1098 ret i1 %r 1099} 1100 1101define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) { 1102; CHECK-LABEL: @is_finite_or_nan_commute( 1103; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 1104; 1105 %cast = uitofp <2 x i8> %x to <2 x float> 1106 %r = fcmp une <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast 1107 ret <2 x i1> %r 1108} 1109 1110; Negative test - but this could be reduced to 'ord' outside of instsimplify. 1111 1112define i1 @is_finite_and_ordered(double %x) { 1113; CHECK-LABEL: @is_finite_and_ordered( 1114; CHECK-NEXT: [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]] 1115; CHECK-NEXT: [[R:%.*]] = fcmp one double [[XX]], 0x7FF0000000000000 1116; CHECK-NEXT: ret i1 [[R]] 1117; 1118 %xx = fmul ninf double %x, %x 1119 %r = fcmp one double %xx, 0x7FF0000000000000 1120 ret i1 %r 1121} 1122 1123define i1 @is_finite(i1 %c, double %x) { 1124; CHECK-LABEL: @is_finite( 1125; CHECK-NEXT: ret i1 true 1126; 1127 %xx = fmul nnan ninf double %x, %x 1128 %s = select i1 %c, double 42.0, double %xx 1129 %r = fcmp one double %s, 0x7FF0000000000000 1130 ret i1 %r 1131} 1132 1133define <2 x i1> @is_finite_commute(<2 x i8> %x) { 1134; CHECK-LABEL: @is_finite_commute( 1135; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 1136; 1137 %cast = uitofp <2 x i8> %x to <2 x float> 1138 %r = fcmp one <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast 1139 ret <2 x i1> %r 1140} 1141 1142; largest unsigned i15 = 2^15 - 1 = 32767 1143; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504 1144 1145define i1 @isKnownNeverInfinity_uitofp(i15 %x) { 1146; CHECK-LABEL: @isKnownNeverInfinity_uitofp( 1147; CHECK-NEXT: ret i1 true 1148; 1149 %f = uitofp i15 %x to half 1150 %r = fcmp une half %f, 0xH7c00 1151 ret i1 %r 1152} 1153 1154; negative test 1155 1156define i1 @isNotKnownNeverInfinity_uitofp(i16 %x) { 1157; CHECK-LABEL: @isNotKnownNeverInfinity_uitofp( 1158; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[X:%.*]] to half 1159; CHECK-NEXT: [[R:%.*]] = fcmp une half [[F]], 0xH7C00 1160; CHECK-NEXT: ret i1 [[R]] 1161; 1162 %f = uitofp i16 %x to half 1163 %r = fcmp une half %f, 0xH7c00 1164 ret i1 %r 1165} 1166 1167define i1 @isKnownNeverNegativeInfinity_uitofp(i15 %x) { 1168; CHECK-LABEL: @isKnownNeverNegativeInfinity_uitofp( 1169; CHECK-NEXT: ret i1 false 1170; 1171 %f = uitofp i15 %x to half 1172 %r = fcmp oeq half %f, 0xHfc00 1173 ret i1 %r 1174} 1175 1176; uitofp can't be negative, so this still works. 1177 1178define i1 @isNotKnownNeverNegativeInfinity_uitofp(i16 %x) { 1179; CHECK-LABEL: @isNotKnownNeverNegativeInfinity_uitofp( 1180; CHECK-NEXT: ret i1 false 1181; 1182 %f = uitofp i16 %x to half 1183 %r = fcmp oeq half %f, 0xHfc00 1184 ret i1 %r 1185} 1186 1187; largest magnitude signed i16 = 2^15 - 1 = 32767 --> -32768 1188; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504 1189 1190define i1 @isKnownNeverInfinity_sitofp(i16 %x) { 1191; CHECK-LABEL: @isKnownNeverInfinity_sitofp( 1192; CHECK-NEXT: ret i1 true 1193; 1194 %f = sitofp i16 %x to half 1195 %r = fcmp une half %f, 0xH7c00 1196 ret i1 %r 1197} 1198 1199; negative test 1200 1201define i1 @isNotKnownNeverInfinity_sitofp(i17 %x) { 1202; CHECK-LABEL: @isNotKnownNeverInfinity_sitofp( 1203; CHECK-NEXT: [[F:%.*]] = sitofp i17 [[X:%.*]] to half 1204; CHECK-NEXT: [[R:%.*]] = fcmp une half [[F]], 0xH7C00 1205; CHECK-NEXT: ret i1 [[R]] 1206; 1207 %f = sitofp i17 %x to half 1208 %r = fcmp une half %f, 0xH7c00 1209 ret i1 %r 1210} 1211 1212define i1 @isKnownNeverNegativeInfinity_sitofp(i16 %x) { 1213; CHECK-LABEL: @isKnownNeverNegativeInfinity_sitofp( 1214; CHECK-NEXT: ret i1 false 1215; 1216 %f = sitofp i16 %x to half 1217 %r = fcmp oeq half %f, 0xHfc00 1218 ret i1 %r 1219} 1220 1221; negative test 1222 1223define i1 @isNotKnownNeverNegativeInfinity_sitofp(i17 %x) { 1224; CHECK-LABEL: @isNotKnownNeverNegativeInfinity_sitofp( 1225; CHECK-NEXT: [[F:%.*]] = sitofp i17 [[X:%.*]] to half 1226; CHECK-NEXT: [[R:%.*]] = fcmp oeq half [[F]], 0xHFC00 1227; CHECK-NEXT: ret i1 [[R]] 1228; 1229 %f = sitofp i17 %x to half 1230 %r = fcmp oeq half %f, 0xHfc00 1231 ret i1 %r 1232} 1233