1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=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 @inf0_fabs(double %arg) { 15; CHECK-LABEL: @inf0_fabs( 16; CHECK-NEXT: ret i1 false 17; 18 %fabs.arg = call double @llvm.fabs.f64(double %arg) 19 %tmp = fcmp ogt double %fabs.arg, 0x7FF0000000000000 20 ret i1 %tmp 21} 22 23define i1 @inf1(double %arg) { 24; CHECK-LABEL: @inf1( 25; CHECK-NEXT: ret i1 true 26; 27 %tmp = fcmp ule double %arg, 0x7FF0000000000000 28 ret i1 %tmp 29} 30 31define i1 @inf1_fabs(double %arg) { 32; CHECK-LABEL: @inf1_fabs( 33; CHECK-NEXT: ret i1 true 34; 35 %fabs.arg = call double @llvm.fabs.f64(double %arg) 36 %tmp = fcmp ule double %fabs.arg, 0x7FF0000000000000 37 ret i1 %tmp 38} 39 40; Negative infinity 41 42define i1 @ninf0(double %arg) { 43; CHECK-LABEL: @ninf0( 44; CHECK-NEXT: ret i1 false 45; 46 %tmp = fcmp olt double %arg, 0xFFF0000000000000 47 ret i1 %tmp 48} 49 50define i1 @ninf0_fabs(double %arg) { 51; CHECK-LABEL: @ninf0_fabs( 52; CHECK-NEXT: ret i1 false 53; 54 %fabs.arg = call double @llvm.fabs.f64(double %arg) 55 %tmp = fcmp olt double %fabs.arg, 0xFFF0000000000000 56 ret i1 %tmp 57} 58 59define i1 @ninf1(double %arg) { 60; CHECK-LABEL: @ninf1( 61; CHECK-NEXT: ret i1 true 62; 63 %tmp = fcmp uge double %arg, 0xFFF0000000000000 64 ret i1 %tmp 65} 66 67define i1 @ninf1_fabs(double %arg) { 68; CHECK-LABEL: @ninf1_fabs( 69; CHECK-NEXT: ret i1 true 70; 71 %fabs.arg = call double @llvm.fabs.f64(double %arg) 72 %tmp = fcmp uge double %fabs.arg, 0xFFF0000000000000 73 ret i1 %tmp 74} 75 76; NaNs 77 78define i1 @nan0(double %arg) { 79; CHECK-LABEL: @nan0( 80; CHECK-NEXT: ret i1 false 81; 82 %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF 83 ret i1 %tmp 84} 85 86define i1 @nan1(double %arg) { 87; CHECK-LABEL: @nan1( 88; CHECK-NEXT: ret i1 false 89; 90 %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF 91 ret i1 %tmp 92} 93 94define i1 @nan2(double %arg) { 95; CHECK-LABEL: @nan2( 96; CHECK-NEXT: ret i1 false 97; 98 %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF 99 ret i1 %tmp 100} 101 102define i1 @nan3(double %arg) { 103; CHECK-LABEL: @nan3( 104; CHECK-NEXT: ret i1 true 105; 106 %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF 107 ret i1 %tmp 108} 109 110define i1 @nan4(double %arg) { 111; CHECK-LABEL: @nan4( 112; CHECK-NEXT: ret i1 true 113; 114 %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF 115 ret i1 %tmp 116} 117 118define i1 @nan5(double %arg) { 119; CHECK-LABEL: @nan5( 120; CHECK-NEXT: ret i1 true 121; 122 %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF 123 ret i1 %tmp 124} 125 126; Negative NaN. 127 128define i1 @nnan0(double %arg) { 129; CHECK-LABEL: @nnan0( 130; CHECK-NEXT: ret i1 false 131; 132 %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF 133 ret i1 %tmp 134} 135 136define i1 @nnan1(double %arg) { 137; CHECK-LABEL: @nnan1( 138; CHECK-NEXT: ret i1 false 139; 140 %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF 141 ret i1 %tmp 142} 143 144define i1 @nnan2(double %arg) { 145; CHECK-LABEL: @nnan2( 146; CHECK-NEXT: ret i1 false 147; 148 %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF 149 ret i1 %tmp 150} 151 152define i1 @nnan3(double %arg) { 153; CHECK-LABEL: @nnan3( 154; CHECK-NEXT: ret i1 true 155; 156 %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF 157 ret i1 %tmp 158} 159 160define i1 @nnan4(double %arg) { 161; CHECK-LABEL: @nnan4( 162; CHECK-NEXT: ret i1 true 163; 164 %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF 165 ret i1 %tmp 166} 167 168define i1 @nnan5(double %arg) { 169; CHECK-LABEL: @nnan5( 170; CHECK-NEXT: ret i1 true 171; 172 %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF 173 ret i1 %tmp 174} 175 176; Negative zero. 177 178define i1 @nzero0() { 179; CHECK-LABEL: @nzero0( 180; CHECK-NEXT: ret i1 true 181; 182 %tmp = fcmp oeq double 0.0, -0.0 183 ret i1 %tmp 184} 185 186define i1 @nzero1() { 187; CHECK-LABEL: @nzero1( 188; CHECK-NEXT: ret i1 false 189; 190 %tmp = fcmp ogt double 0.0, -0.0 191 ret i1 %tmp 192} 193 194; No enlightenment here. 195 196define i1 @one_with_self(double %arg) { 197; CHECK-LABEL: @one_with_self( 198; CHECK-NEXT: ret i1 false 199; 200 %tmp = fcmp one double %arg, %arg 201 ret i1 %tmp 202} 203 204; These tests choose arbitrarily between float and double, 205; and between uge and olt, to give reasonble coverage 206; without combinatorial explosion. 207 208define i1 @orderedLessZeroTree(float,float,float,float) { 209; CHECK-LABEL: @orderedLessZeroTree( 210; CHECK-NEXT: ret i1 true 211; 212 %square = fmul float %0, %0 213 %abs = call float @llvm.fabs.f32(float %1) 214 %sqrt = call float @llvm.sqrt.f32(float %2) 215 %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt) 216 %div = fdiv float %square, %abs 217 %rem = frem float %sqrt, %fma 218 %add = fadd float %div, %rem 219 %uge = fcmp uge float %add, 0.000000e+00 220 ret i1 %uge 221} 222 223define i1 @orderedLessZero_fdiv(float %x) { 224; CHECK-LABEL: @orderedLessZero_fdiv( 225; CHECK-NEXT: ret i1 true 226; 227 %d = fdiv float %x, %x 228 %uge = fcmp uge float %d, 0.0 229 ret i1 %uge 230} 231 232; If x == -0.0, maxnum can return -0.0, but that still compares equal to 0.0. 233 234define i1 @orderedLessZero_maxnum(float %x) { 235; CHECK-LABEL: @orderedLessZero_maxnum( 236; CHECK-NEXT: ret i1 true 237; 238 %d = call float @llvm.maxnum.f32(float %x, float 0.0) 239 %uge = fcmp uge float %d, 0.0 240 ret i1 %uge 241} 242 243define i1 @orderedLessZeroExpExt(float) { 244; CHECK-LABEL: @orderedLessZeroExpExt( 245; CHECK-NEXT: ret i1 true 246; 247 %a = call float @llvm.exp.f32(float %0) 248 %b = fpext float %a to double 249 %uge = fcmp uge double %b, 0.000000e+00 250 ret i1 %uge 251} 252 253define i1 @orderedLessZeroExp2Trunc(double) { 254; CHECK-LABEL: @orderedLessZeroExp2Trunc( 255; CHECK-NEXT: ret i1 false 256; 257 %a = call double @llvm.exp2.f64(double %0) 258 %b = fptrunc double %a to float 259 %olt = fcmp olt float %b, 0.000000e+00 260 ret i1 %olt 261} 262 263define i1 @orderedLessZeroPowi(double,double) { 264; CHECK-LABEL: @orderedLessZeroPowi( 265; CHECK-NEXT: ret i1 false 266; 267 ; Even constant exponent 268 %a = call double @llvm.powi.f64.i32(double %0, i32 2) 269 %square = fmul double %1, %1 270 ; Odd constant exponent with provably non-negative base 271 %b = call double @llvm.powi.f64.i32(double %square, i32 3) 272 %c = fadd double %a, %b 273 %olt = fcmp olt double %b, 0.000000e+00 274 ret i1 %olt 275} 276 277define i1 @UIToFP_is_nan_or_positive_or_zero(i32 %x) { 278; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero( 279; CHECK-NEXT: ret i1 true 280; 281 %a = uitofp i32 %x to float 282 %r = fcmp uge float %a, 0.000000e+00 283 ret i1 %r 284} 285 286define <2 x i1> @UIToFP_is_nan_or_positive_or_zero_vec(<2 x i32> %x) { 287; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero_vec( 288; CHECK-NEXT: ret <2 x i1> splat (i1 true) 289; 290 %a = uitofp <2 x i32> %x to <2 x float> 291 %r = fcmp uge <2 x float> %a, zeroinitializer 292 ret <2 x i1> %r 293} 294 295define i1 @UIToFP_is_positive_or_zero(i32 %x) { 296; CHECK-LABEL: @UIToFP_is_positive_or_zero( 297; CHECK-NEXT: ret i1 true 298; 299 %a = uitofp i32 %x to float 300 %r = fcmp oge float %a, 0.000000e+00 301 ret i1 %r 302} 303 304define <2 x i1> @UIToFP_is_positive_or_zero_vec(<2 x i32> %x) { 305; CHECK-LABEL: @UIToFP_is_positive_or_zero_vec( 306; CHECK-NEXT: ret <2 x i1> splat (i1 true) 307; 308 %a = uitofp <2 x i32> %x to <2 x float> 309 %r = fcmp oge <2 x float> %a, zeroinitializer 310 ret <2 x i1> %r 311} 312 313define i1 @UIToFP_nnan_is_positive_or_zero(i32 %x) { 314; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero( 315; CHECK-NEXT: ret i1 true 316; 317 %a = uitofp i32 %x to float 318 %r = fcmp nnan oge float %a, 0.000000e+00 319 ret i1 %r 320} 321 322define <2 x i1> @UIToFP_nnan_is_positive_or_zero_vec(<2 x i32> %x) { 323; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero_vec( 324; CHECK-NEXT: ret <2 x i1> splat (i1 true) 325; 326 %a = uitofp <2 x i32> %x to <2 x float> 327 %r = fcmp nnan oge <2 x float> %a, zeroinitializer 328 ret <2 x i1> %r 329} 330 331define i1 @UIToFP_is_not_negative(i32 %x) { 332; CHECK-LABEL: @UIToFP_is_not_negative( 333; CHECK-NEXT: ret i1 false 334; 335 %a = uitofp i32 %x to float 336 %r = fcmp olt float %a, 0.000000e+00 337 ret i1 %r 338} 339 340define <2 x i1> @UIToFP_is_not_negative_vec(<2 x i32> %x) { 341; CHECK-LABEL: @UIToFP_is_not_negative_vec( 342; CHECK-NEXT: ret <2 x i1> zeroinitializer 343; 344 %a = uitofp <2 x i32> %x to <2 x float> 345 %r = fcmp olt <2 x float> %a, zeroinitializer 346 ret <2 x i1> %r 347} 348 349; No FMF are required for this transform. 350 351define i1 @UIToFP_is_not_negative_or_nan(i32 %x) { 352; CHECK-LABEL: @UIToFP_is_not_negative_or_nan( 353; CHECK-NEXT: ret i1 false 354; 355 %a = uitofp i32 %x to float 356 %r = fcmp ult float %a, 0.000000e+00 357 ret i1 %r 358} 359 360define <2 x i1> @UIToFP_is_not_negative_or_nan_vec(<2 x i32> %x) { 361; CHECK-LABEL: @UIToFP_is_not_negative_or_nan_vec( 362; CHECK-NEXT: ret <2 x i1> zeroinitializer 363; 364 %a = uitofp <2 x i32> %x to <2 x float> 365 %r = fcmp ult <2 x float> %a, zeroinitializer 366 ret <2 x i1> %r 367} 368 369define i1 @UIToFP_nnan_is_not_negative(i32 %x) { 370; CHECK-LABEL: @UIToFP_nnan_is_not_negative( 371; CHECK-NEXT: ret i1 false 372; 373 %a = uitofp i32 %x to float 374 %r = fcmp nnan ult float %a, 0.000000e+00 375 ret i1 %r 376} 377 378define <2 x i1> @UIToFP_nnan_is_not_negative_vec(<2 x i32> %x) { 379; CHECK-LABEL: @UIToFP_nnan_is_not_negative_vec( 380; CHECK-NEXT: ret <2 x i1> zeroinitializer 381; 382 %a = uitofp <2 x i32> %x to <2 x float> 383 %r = fcmp nnan ult <2 x float> %a, zeroinitializer 384 ret <2 x i1> %r 385} 386 387define i1 @fabs_is_nan_or_positive_or_zero(double %x) { 388; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero( 389; CHECK-NEXT: ret i1 true 390; 391 %fabs = tail call double @llvm.fabs.f64(double %x) 392 %cmp = fcmp uge double %fabs, 0.0 393 ret i1 %cmp 394} 395 396define <2 x i1> @fabs_is_nan_or_positive_or_zero_vec(<2 x double> %x) { 397; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero_vec( 398; CHECK-NEXT: ret <2 x i1> splat (i1 true) 399; 400 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 401 %cmp = fcmp uge <2 x double> %fabs, zeroinitializer 402 ret <2 x i1> %cmp 403} 404 405define i1 @fabs_nnan_is_positive_or_zero(double %x) { 406; CHECK-LABEL: @fabs_nnan_is_positive_or_zero( 407; CHECK-NEXT: ret i1 true 408; 409 %fabs = tail call nnan double @llvm.fabs.f64(double %x) 410 %cmp = fcmp oge double %fabs, 0.0 411 ret i1 %cmp 412} 413 414define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) { 415; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec( 416; CHECK-NEXT: ret <2 x i1> splat (i1 true) 417; 418 %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 419 %cmp = fcmp oge <2 x double> %fabs, zeroinitializer 420 ret <2 x i1> %cmp 421} 422 423define i1 @fabs_fcmp-nnan_is_positive_or_zero(double %x) { 424; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero( 425; CHECK-NEXT: ret i1 true 426; 427 %fabs = tail call double @llvm.fabs.f64(double %x) 428 %cmp = fcmp nnan oge double %fabs, 0.0 429 ret i1 %cmp 430} 431 432define i1 @fabs_fcmp_oge0-assume-nnan_is_positive_or_zero(double %x) { 433; CHECK-LABEL: @fabs_fcmp_oge0-assume-nnan_is_positive_or_zero( 434; CHECK-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 435; CHECK-NEXT: [[ORD:%.*]] = fcmp ord double [[FABS]], 0.000000e+00 436; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]]) 437; CHECK-NEXT: ret i1 true 438; 439 %fabs = tail call double @llvm.fabs.f64(double %x) 440 %ord = fcmp ord double %fabs, 0.0 441 call void @llvm.assume(i1 %ord) 442 %cmp = fcmp oge double %fabs, 0.0 443 ret i1 %cmp 444} 445 446define i1 @fabs_fcmp_olt0_-assume-nnan_is_positive_or_zero(double %x) { 447; CHECK-LABEL: @fabs_fcmp_olt0_-assume-nnan_is_positive_or_zero( 448; CHECK-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 449; CHECK-NEXT: [[ORD:%.*]] = fcmp ord double [[FABS]], 0.000000e+00 450; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]]) 451; CHECK-NEXT: ret i1 false 452; 453 %fabs = tail call double @llvm.fabs.f64(double %x) 454 %ord = fcmp ord double %fabs, 0.0 455 call void @llvm.assume(i1 %ord) 456 %cmp = fcmp olt double %fabs, 0.0 457 ret i1 %cmp 458} 459 460define <2 x i1> @fabs_fcmp-nnan_is_positive_or_zero_vec(<2 x double> %x) { 461; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero_vec( 462; CHECK-NEXT: ret <2 x i1> splat (i1 true) 463; 464 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 465 %cmp = fcmp nnan oge <2 x double> %fabs, zeroinitializer 466 ret <2 x i1> %cmp 467} 468 469define i1 @fabs_is_not_negative(double %x) { 470; CHECK-LABEL: @fabs_is_not_negative( 471; CHECK-NEXT: ret i1 false 472; 473 %fabs = tail call double @llvm.fabs.f64(double %x) 474 %cmp = fcmp olt double %fabs, 0.0 475 ret i1 %cmp 476} 477 478define <2 x i1> @fabs_is_not_negative_vec(<2 x double> %x) { 479; CHECK-LABEL: @fabs_is_not_negative_vec( 480; CHECK-NEXT: ret <2 x i1> zeroinitializer 481; 482 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 483 %cmp = fcmp olt <2 x double> %fabs, zeroinitializer 484 ret <2 x i1> %cmp 485} 486 487define i1 @fabs_nnan_is_not_negative(double %x) { 488; CHECK-LABEL: @fabs_nnan_is_not_negative( 489; CHECK-NEXT: ret i1 false 490; 491 %fabs = tail call nnan double @llvm.fabs.f64(double %x) 492 %cmp = fcmp ult double %fabs, 0.0 493 ret i1 %cmp 494} 495 496define <2 x i1> @fabs_nnan_is_not_negative_vec(<2 x double> %x) { 497; CHECK-LABEL: @fabs_nnan_is_not_negative_vec( 498; CHECK-NEXT: ret <2 x i1> zeroinitializer 499; 500 %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 501 %cmp = fcmp ult <2 x double> %fabs, zeroinitializer 502 ret <2 x i1> %cmp 503} 504 505define i1 @fabs_fcmp-nnan_is_not_negative(double %x) { 506; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative( 507; CHECK-NEXT: ret i1 false 508; 509 %fabs = tail call double @llvm.fabs.f64(double %x) 510 %cmp = fcmp nnan ult double %fabs, 0.0 511 ret i1 %cmp 512} 513 514define <2 x i1> @fabs_fcmp-nnan_is_not_negative_vec(<2 x double> %x) { 515; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative_vec( 516; CHECK-NEXT: ret <2 x i1> zeroinitializer 517; 518 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 519 %cmp = fcmp nnan ult <2 x double> %fabs, zeroinitializer 520 ret <2 x i1> %cmp 521} 522 523define <2 x i1> @fabs_is_not_negative_negzero(<2 x float> %V) { 524; CHECK-LABEL: @fabs_is_not_negative_negzero( 525; CHECK-NEXT: ret <2 x i1> zeroinitializer 526; 527 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 528 %cmp = fcmp olt <2 x float> %abs, <float -0.0, float -0.0> 529 ret <2 x i1> %cmp 530} 531 532define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) { 533; CHECK-LABEL: @fabs_is_not_negative_poszero( 534; CHECK-NEXT: ret <2 x i1> zeroinitializer 535; 536 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 537 %cmp = fcmp olt <2 x float> %abs, <float 0.0, float 0.0> 538 ret <2 x i1> %cmp 539} 540 541define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) { 542; CHECK-LABEL: @fabs_is_not_negative_anyzero( 543; CHECK-NEXT: ret <2 x i1> zeroinitializer 544; 545 %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) 546 %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0> 547 ret <2 x i1> %cmp 548} 549 550define <3 x i1> @fabs_is_not_negative_negzero_poison(<3 x float> %V) { 551; CHECK-LABEL: @fabs_is_not_negative_negzero_poison( 552; CHECK-NEXT: ret <3 x i1> zeroinitializer 553; 554 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 555 %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float poison> 556 ret <3 x i1> %cmp 557} 558 559define <3 x i1> @fabs_is_not_negative_poszero_poison(<3 x float> %V) { 560; CHECK-LABEL: @fabs_is_not_negative_poszero_poison( 561; CHECK-NEXT: ret <3 x i1> zeroinitializer 562; 563 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 564 %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float poison> 565 ret <3 x i1> %cmp 566} 567 568define <3 x i1> @fabs_is_not_negative_anyzero_poison(<3 x float> %V) { 569; CHECK-LABEL: @fabs_is_not_negative_anyzero_poison( 570; CHECK-NEXT: ret <3 x i1> zeroinitializer 571; 572 %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) 573 %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float poison> 574 ret <3 x i1> %cmp 575} 576 577define i1 @orderedLessZeroSelect(float, float) { 578; CHECK-LABEL: @orderedLessZeroSelect( 579; CHECK-NEXT: ret i1 true 580; 581 %a = call float @llvm.exp.f32(float %0) 582 %b = call float @llvm.fabs.f32(float %1) 583 %c = fcmp olt float %0, %1 584 %d = select i1 %c, float %a, float %b 585 %e = fadd float %d, 1.0 586 %uge = fcmp uge float %e, 0.000000e+00 587 ret i1 %uge 588} 589 590define i1 @orderedLessZeroMinNum(float, float) { 591; CHECK-LABEL: @orderedLessZeroMinNum( 592; CHECK-NEXT: ret i1 true 593; 594 %a = call float @llvm.exp.f32(float %0) 595 %b = call float @llvm.fabs.f32(float %1) 596 %c = call float @llvm.minnum.f32(float %a, float %b) 597 %uge = fcmp uge float %c, 0.000000e+00 598 ret i1 %uge 599} 600 601; PR37776: https://bugs.llvm.org/show_bug.cgi?id=37776 602; exp() may return nan, leaving %1 as the unknown result, so we can't simplify. 603 604define i1 @orderedLessZeroMaxNum(float, float) { 605; CHECK-LABEL: @orderedLessZeroMaxNum( 606; CHECK-NEXT: [[A:%.*]] = call float @llvm.exp.f32(float [[TMP0:%.*]]) 607; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[TMP1:%.*]]) 608; CHECK-NEXT: [[UGE:%.*]] = fcmp uge float [[B]], 0.000000e+00 609; CHECK-NEXT: ret i1 [[UGE]] 610; 611 %a = call float @llvm.exp.f32(float %0) 612 %b = call float @llvm.maxnum.f32(float %a, float %1) 613 %uge = fcmp uge float %b, 0.000000e+00 614 ret i1 %uge 615} 616 617; But using maximum, we can simplify, since the NaN would be propagated 618 619define i1 @orderedLessZeroMaximum(float, float) { 620; CHECK-LABEL: @orderedLessZeroMaximum( 621; CHECK-NEXT: ret i1 true 622; 623 %a = call float @llvm.exp.f32(float %0) 624 %b = call float @llvm.maximum.f32(float %a, float %1) 625 %uge = fcmp uge float %b, 0.000000e+00 626 ret i1 %uge 627} 628 629define i1 @minnum_non_nan(float %x) { 630; CHECK-LABEL: @minnum_non_nan( 631; CHECK-NEXT: ret i1 true 632; 633 %min = call float @llvm.minnum.f32(float 0.5, float %x) 634 %cmp = fcmp ord float %min, 1.0 635 ret i1 %cmp 636} 637 638define i1 @maxnum_non_nan(float %x) { 639; CHECK-LABEL: @maxnum_non_nan( 640; CHECK-NEXT: ret i1 false 641; 642 %min = call float @llvm.maxnum.f32(float %x, float 42.0) 643 %cmp = fcmp uno float %min, 12.0 644 ret i1 %cmp 645} 646 647define i1 @assume_nonnan_ord(float %x) { 648; CHECK-LABEL: @assume_nonnan_ord( 649; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 650; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]]) 651; CHECK-NEXT: ret i1 true 652; 653 %ord = fcmp ord float %x, 0.0 654 call void @llvm.assume(i1 %ord) 655 %cmp = fcmp ord float %x, 1.0 656 ret i1 %cmp 657} 658 659define i1 @assume_nonnan_x2_ord(float %x, float %y) { 660; CHECK-LABEL: @assume_nonnan_x2_ord( 661; CHECK-NEXT: [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 662; CHECK-NEXT: call void @llvm.assume(i1 [[ORD_X]]) 663; CHECK-NEXT: [[ORD_Y:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00 664; CHECK-NEXT: call void @llvm.assume(i1 [[ORD_Y]]) 665; CHECK-NEXT: ret i1 true 666; 667 %ord.x = fcmp ord float %x, 0.0 668 call void @llvm.assume(i1 %ord.x) 669 %ord.y = fcmp ord float %y, 0.0 670 call void @llvm.assume(i1 %ord.y) 671 %cmp = fcmp ord float %x, %y 672 ret i1 %cmp 673} 674 675define i1 @assume_nan_x2_uno(float %x, float %y) { 676; CHECK-LABEL: @assume_nan_x2_uno( 677; CHECK-NEXT: [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 678; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_X]]) 679; CHECK-NEXT: [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00 680; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_Y]]) 681; CHECK-NEXT: ret i1 true 682; 683 %uno.x = fcmp uno float %x, 0.0 684 call void @llvm.assume(i1 %uno.x) 685 %uno.y = fcmp uno float %y, 0.0 686 call void @llvm.assume(i1 %uno.y) 687 %cmp = fcmp uno float %x, %y 688 ret i1 %cmp 689} 690 691define i1 @assume_nan_x2_ord(float %x, float %y) { 692; CHECK-LABEL: @assume_nan_x2_ord( 693; CHECK-NEXT: [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 694; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_X]]) 695; CHECK-NEXT: [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00 696; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_Y]]) 697; CHECK-NEXT: ret i1 false 698; 699 %uno.x = fcmp uno float %x, 0.0 700 call void @llvm.assume(i1 %uno.x) 701 %uno.y = fcmp uno float %y, 0.0 702 call void @llvm.assume(i1 %uno.y) 703 %cmp = fcmp ord float %x, %y 704 ret i1 %cmp 705} 706 707define i1 @assume_nonan_x2_uno(float %x, float %y) { 708; CHECK-LABEL: @assume_nonan_x2_uno( 709; CHECK-NEXT: [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 710; CHECK-NEXT: call void @llvm.assume(i1 [[ORD_X]]) 711; CHECK-NEXT: [[ORD_Y:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00 712; CHECK-NEXT: call void @llvm.assume(i1 [[ORD_Y]]) 713; CHECK-NEXT: ret i1 false 714; 715 %ord.x = fcmp ord float %x, 0.0 716 call void @llvm.assume(i1 %ord.x) 717 %ord.y = fcmp ord float %y, 0.0 718 call void @llvm.assume(i1 %ord.y) 719 %cmp = fcmp uno float %x, %y 720 ret i1 %cmp 721} 722 723define i1 @assume_nan_ord(float %x) { 724; CHECK-LABEL: @assume_nan_ord( 725; CHECK-NEXT: [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 726; CHECK-NEXT: call void @llvm.assume(i1 [[UNO]]) 727; CHECK-NEXT: ret i1 false 728; 729 %uno = fcmp uno float %x, 0.0 730 call void @llvm.assume(i1 %uno) 731 %cmp = fcmp ord float %x, 1.0 732 ret i1 %cmp 733} 734 735define i1 @assume_nonnan_uno(float %x) { 736; CHECK-LABEL: @assume_nonnan_uno( 737; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 738; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]]) 739; CHECK-NEXT: ret i1 false 740; 741 %ord = fcmp ord float %x, 0.0 742 call void @llvm.assume(i1 %ord) 743 %cmp = fcmp uno float %x, 1.0 744 ret i1 %cmp 745} 746 747define i1 @assume_nan_uno(float %x) { 748; CHECK-LABEL: @assume_nan_uno( 749; CHECK-NEXT: [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 750; CHECK-NEXT: call void @llvm.assume(i1 [[UNO]]) 751; CHECK-NEXT: ret i1 true 752; 753 %uno = fcmp uno float %x, 0.0 754 call void @llvm.assume(i1 %uno) 755 %cmp = fcmp uno float %x, 1.0 756 ret i1 %cmp 757} 758 759; min(x, 0.5) == 1.0 --> false 760 761define i1 @minnum_oeq_small_min_constant(float %x) { 762; CHECK-LABEL: @minnum_oeq_small_min_constant( 763; CHECK-NEXT: ret i1 false 764; 765 %min = call float @llvm.minnum.f32(float %x, float 0.5) 766 %cmp = fcmp oeq float %min, 1.0 767 ret i1 %cmp 768} 769 770; min(x, 0.5) > 1.0 --> false 771 772define i1 @minnum_ogt_small_min_constant(float %x) { 773; CHECK-LABEL: @minnum_ogt_small_min_constant( 774; CHECK-NEXT: ret i1 false 775; 776 %min = call float @llvm.minnum.f32(float %x, float 0.5) 777 %cmp = fcmp ogt float %min, 1.0 778 ret i1 %cmp 779} 780 781; min(x, 0.5) >= 1.0 --> false 782 783define i1 @minnum_oge_small_min_constant(float %x) { 784; CHECK-LABEL: @minnum_oge_small_min_constant( 785; CHECK-NEXT: ret i1 false 786; 787 %min = call float @llvm.minnum.f32(float %x, float 0.5) 788 %cmp = fcmp oge float %min, 1.0 789 ret i1 %cmp 790} 791 792; min(x, 0.5) == 1.0 --> false 793 794define i1 @minnum_ueq_small_min_constant(float %x) { 795; CHECK-LABEL: @minnum_ueq_small_min_constant( 796; CHECK-NEXT: ret i1 false 797; 798 %min = call float @llvm.minnum.f32(float %x, float 0.5) 799 %cmp = fcmp ueq float %min, 1.0 800 ret i1 %cmp 801} 802 803; min(x, 0.5) > 1.0 --> false 804 805define i1 @minnum_ugt_small_min_constant(float %x) { 806; CHECK-LABEL: @minnum_ugt_small_min_constant( 807; CHECK-NEXT: ret i1 false 808; 809 %min = call float @llvm.minnum.f32(float %x, float 0.5) 810 %cmp = fcmp ugt float %min, 1.0 811 ret i1 %cmp 812} 813 814; min(x, 0.5) >= 1.0 --> false 815 816define <2 x i1> @minnum_uge_small_min_constant(<2 x float> %x) { 817; CHECK-LABEL: @minnum_uge_small_min_constant( 818; CHECK-NEXT: ret <2 x i1> zeroinitializer 819; 820 %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>) 821 %cmp = fcmp uge <2 x float> %min, <float 1.0, float 1.0> 822 ret <2 x i1> %cmp 823} 824 825; min(x, 0.5) < 1.0 --> true 826 827define <2 x i1> @minnum_olt_small_min_constant(<2 x float> %x) { 828; CHECK-LABEL: @minnum_olt_small_min_constant( 829; CHECK-NEXT: ret <2 x i1> splat (i1 true) 830; 831 %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>) 832 %cmp = fcmp olt <2 x float> %min, <float 1.0, float 1.0> 833 ret <2 x i1> %cmp 834} 835 836; min(x, 0.5) <= 1.0 --> true 837 838define i1 @minnum_ole_small_min_constant(float %x) { 839; CHECK-LABEL: @minnum_ole_small_min_constant( 840; CHECK-NEXT: ret i1 true 841; 842 %min = call float @llvm.minnum.f32(float %x, float 0.5) 843 %cmp = fcmp ole float %min, 1.0 844 ret i1 %cmp 845} 846 847; min(x, 0.5) != 1.0 --> true 848 849define i1 @minnum_one_small_min_constant(float %x) { 850; CHECK-LABEL: @minnum_one_small_min_constant( 851; CHECK-NEXT: ret i1 true 852; 853 %min = call float @llvm.minnum.f32(float %x, float 0.5) 854 %cmp = fcmp one float %min, 1.0 855 ret i1 %cmp 856} 857 858; min(x, 0.5) < 1.0 --> true 859 860define i1 @minnum_ult_small_min_constant(float %x) { 861; CHECK-LABEL: @minnum_ult_small_min_constant( 862; CHECK-NEXT: ret i1 true 863; 864 %min = call float @llvm.minnum.f32(float %x, float 0.5) 865 %cmp = fcmp ult float %min, 1.0 866 ret i1 %cmp 867} 868 869; min(x, 0.5) <= 1.0 --> true 870 871define i1 @minnum_ule_small_min_constant(float %x) { 872; CHECK-LABEL: @minnum_ule_small_min_constant( 873; CHECK-NEXT: ret i1 true 874; 875 %min = call float @llvm.minnum.f32(float %x, float 0.5) 876 %cmp = fcmp ule float %min, 1.0 877 ret i1 %cmp 878} 879 880; min(x, 0.5) != 1.0 --> true 881 882define i1 @minnum_une_small_min_constant(float %x) { 883; CHECK-LABEL: @minnum_une_small_min_constant( 884; CHECK-NEXT: ret i1 true 885; 886 %min = call float @llvm.minnum.f32(float %x, float 0.5) 887 %cmp = fcmp une float %min, 1.0 888 ret i1 %cmp 889} 890 891; Negative test: 892; min(x, 1.0) != 1.0 --> ? 893 894define i1 @minnum_une_equal_min_constant(float %x) { 895; CHECK-LABEL: @minnum_une_equal_min_constant( 896; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00) 897; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00 898; CHECK-NEXT: ret i1 [[CMP]] 899; 900 %min = call float @llvm.minnum.f32(float %x, float 1.0) 901 %cmp = fcmp une float %min, 1.0 902 ret i1 %cmp 903} 904 905; Negative test: 906; min(x, 2.0) != 1.0 --> ? 907 908define i1 @minnum_une_large_min_constant(float %x) { 909; CHECK-LABEL: @minnum_une_large_min_constant( 910; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.000000e+00) 911; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00 912; CHECK-NEXT: ret i1 [[CMP]] 913; 914 %min = call float @llvm.minnum.f32(float %x, float 2.0) 915 %cmp = fcmp une float %min, 1.0 916 ret i1 %cmp 917} 918 919; Partial negative test (the minnum simplifies): 920; min(x, NaN) != 1.0 --> x != 1.0 921 922define i1 @minnum_une_nan_min_constant(float %x) { 923; CHECK-LABEL: @minnum_une_nan_min_constant( 924; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00 925; CHECK-NEXT: ret i1 [[CMP]] 926; 927 %min = call float @llvm.minnum.f32(float %x, float 0x7FF8000000000000) 928 %cmp = fcmp une float %min, 1.0 929 ret i1 %cmp 930} 931 932; max(x, 1.5) == 1.0 --> false 933 934define i1 @maxnum_oeq_large_max_constant(float %x) { 935; CHECK-LABEL: @maxnum_oeq_large_max_constant( 936; CHECK-NEXT: ret i1 false 937; 938 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 939 %cmp = fcmp oeq float %max, 1.0 940 ret i1 %cmp 941} 942 943; max(x, 1.5) < 1.0 --> false 944 945define i1 @maxnum_olt_large_max_constant(float %x) { 946; CHECK-LABEL: @maxnum_olt_large_max_constant( 947; CHECK-NEXT: ret i1 false 948; 949 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 950 %cmp = fcmp olt float %max, 1.0 951 ret i1 %cmp 952} 953 954; max(x, 1.5) <= 1.0 --> false 955 956define i1 @maxnum_ole_large_max_constant(float %x) { 957; CHECK-LABEL: @maxnum_ole_large_max_constant( 958; CHECK-NEXT: ret i1 false 959; 960 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 961 %cmp = fcmp ole float %max, 1.0 962 ret i1 %cmp 963} 964 965; max(x, 1.5) == 1.0 --> false 966 967define i1 @maxnum_ueq_large_max_constant(float %x) { 968; CHECK-LABEL: @maxnum_ueq_large_max_constant( 969; CHECK-NEXT: ret i1 false 970; 971 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 972 %cmp = fcmp ueq float %max, 1.0 973 ret i1 %cmp 974} 975 976; max(x, 1.5) < 1.0 --> false 977 978define i1 @maxnum_ult_large_max_constant(float %x) { 979; CHECK-LABEL: @maxnum_ult_large_max_constant( 980; CHECK-NEXT: ret i1 false 981; 982 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 983 %cmp = fcmp ult float %max, 1.0 984 ret i1 %cmp 985} 986 987; max(x, 1.5) <= 1.0 --> false 988 989define <2 x i1> @maxnum_ule_large_max_constant(<2 x float> %x) { 990; CHECK-LABEL: @maxnum_ule_large_max_constant( 991; CHECK-NEXT: ret <2 x i1> zeroinitializer 992; 993 %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>) 994 %cmp = fcmp ule <2 x float> %max, <float 1.0, float 1.0> 995 ret <2 x i1> %cmp 996} 997 998; max(x, 1.5) > 1.0 --> true 999 1000define <2 x i1> @maxnum_ogt_large_max_constant(<2 x float> %x) { 1001; CHECK-LABEL: @maxnum_ogt_large_max_constant( 1002; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1003; 1004 %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>) 1005 %cmp = fcmp ogt <2 x float> %max, <float 1.0, float 1.0> 1006 ret <2 x i1> %cmp 1007} 1008 1009; max(x, 1.5) >= 1.0 --> true 1010 1011define i1 @maxnum_oge_large_max_constant(float %x) { 1012; CHECK-LABEL: @maxnum_oge_large_max_constant( 1013; CHECK-NEXT: ret i1 true 1014; 1015 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 1016 %cmp = fcmp oge float %max, 1.0 1017 ret i1 %cmp 1018} 1019 1020; max(x, 1.5) != 1.0 --> true 1021 1022define i1 @maxnum_one_large_max_constant(float %x) { 1023; CHECK-LABEL: @maxnum_one_large_max_constant( 1024; CHECK-NEXT: ret i1 true 1025; 1026 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 1027 %cmp = fcmp one float %max, 1.0 1028 ret i1 %cmp 1029} 1030 1031; max(x, 1.5) > 1.0 --> true 1032 1033define i1 @maxnum_ugt_large_max_constant(float %x) { 1034; CHECK-LABEL: @maxnum_ugt_large_max_constant( 1035; CHECK-NEXT: ret i1 true 1036; 1037 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 1038 %cmp = fcmp ugt float %max, 1.0 1039 ret i1 %cmp 1040} 1041 1042; max(x, 1.5) >= 1.0 --> true 1043 1044define i1 @maxnum_uge_large_max_constant(float %x) { 1045; CHECK-LABEL: @maxnum_uge_large_max_constant( 1046; CHECK-NEXT: ret i1 true 1047; 1048 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 1049 %cmp = fcmp uge float %max, 1.0 1050 ret i1 %cmp 1051} 1052 1053; max(x, 1.5) != 1.0 --> true 1054 1055define i1 @maxnum_une_large_max_constant(float %x) { 1056; CHECK-LABEL: @maxnum_une_large_max_constant( 1057; CHECK-NEXT: ret i1 true 1058; 1059 %max = call float @llvm.maxnum.f32(float %x, float 1.5) 1060 %cmp = fcmp une float %max, 1.0 1061 ret i1 %cmp 1062} 1063 1064; Negative test: 1065; max(x, 1.0) != 1.0 --> ? 1066 1067define i1 @maxnum_une_equal_max_constant(float %x) { 1068; CHECK-LABEL: @maxnum_une_equal_max_constant( 1069; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00) 1070; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00 1071; CHECK-NEXT: ret i1 [[CMP]] 1072; 1073 %max = call float @llvm.maxnum.f32(float %x, float 1.0) 1074 %cmp = fcmp une float %max, 1.0 1075 ret i1 %cmp 1076} 1077 1078; Negative test: 1079; max(x, 0.5) != 1.0 --> ? 1080 1081define i1 @maxnum_une_small_max_constant(float %x) { 1082; CHECK-LABEL: @maxnum_une_small_max_constant( 1083; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 5.000000e-01) 1084; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00 1085; CHECK-NEXT: ret i1 [[CMP]] 1086; 1087 %max = call float @llvm.maxnum.f32(float %x, float 0.5) 1088 %cmp = fcmp une float %max, 1.0 1089 ret i1 %cmp 1090} 1091 1092; Partial negative test (the maxnum simplifies): 1093; max(x, NaN) != 1.0 --> x != 1.0 1094 1095define i1 @maxnum_une_nan_max_constant(float %x) { 1096; CHECK-LABEL: @maxnum_une_nan_max_constant( 1097; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00 1098; CHECK-NEXT: ret i1 [[CMP]] 1099; 1100 %max = call float @llvm.maxnum.f32(float %x, float 0x7FF8000000000000) 1101 %cmp = fcmp une float %max, 1.0 1102 ret i1 %cmp 1103} 1104 1105define i1 @known_positive_olt_with_negative_constant(double %a) { 1106; CHECK-LABEL: @known_positive_olt_with_negative_constant( 1107; CHECK-NEXT: ret i1 false 1108; 1109 %call = call double @llvm.fabs.f64(double %a) 1110 %cmp = fcmp olt double %call, -1.0 1111 ret i1 %cmp 1112} 1113 1114define i1 @known_positive_nsz_olt_with_negative_constant(double %mag, double %a) { 1115; CHECK-LABEL: @known_positive_nsz_olt_with_negative_constant( 1116; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]]) 1117; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1118; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00 1119; CHECK-NEXT: ret i1 [[CMP]] 1120; 1121 %sqrt = call nsz double @llvm.sqrt.f64(double %a) 1122 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1123 %cmp = fcmp olt double %copysign, -1.0 1124 ret i1 %cmp 1125} 1126 1127define i1 @known_positive_maybe_neg0_olt_with_negative_constant(double %mag, double %a) { 1128; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_negative_constant( 1129; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]]) 1130; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1131; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00 1132; CHECK-NEXT: ret i1 [[CMP]] 1133; 1134 %sqrt = call double @llvm.sqrt.f64(double %a) 1135 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1136 %cmp = fcmp olt double %copysign, -1.0 1137 ret i1 %cmp 1138} 1139 1140define i1 @known_positive_nsz_uge_with_negative_constant(double %mag, double %a) { 1141; CHECK-LABEL: @known_positive_nsz_uge_with_negative_constant( 1142; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]]) 1143; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1144; CHECK-NEXT: [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00 1145; CHECK-NEXT: ret i1 [[CMP]] 1146; 1147 %sqrt = call nsz double @llvm.sqrt.f64(double %a) 1148 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1149 %cmp = fcmp uge double %copysign, -1.0 1150 ret i1 %cmp 1151} 1152 1153define i1 @known_positive_maybe_neg0_uge_with_negative_constant(double %mag, double %a) { 1154; CHECK-LABEL: @known_positive_maybe_neg0_uge_with_negative_constant( 1155; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]]) 1156; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1157; CHECK-NEXT: [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00 1158; CHECK-NEXT: ret i1 [[CMP]] 1159; 1160 %sqrt = call double @llvm.sqrt.f64(double %a) 1161 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1162 %cmp = fcmp uge double %copysign, -1.0 1163 ret i1 %cmp 1164} 1165 1166define i1 @known_positive_nsz_oge_with_zero_constant(double %mag, double %a) { 1167; CHECK-LABEL: @known_positive_nsz_oge_with_zero_constant( 1168; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]]) 1169; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1170; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00 1171; CHECK-NEXT: ret i1 [[CMP]] 1172; 1173 %sqrt = call nsz double @llvm.sqrt.f64(double %a) 1174 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1175 %cmp = fcmp oge double %copysign, 0.0 1176 ret i1 %cmp 1177} 1178 1179define i1 @known_positive_maybe_neg0_oge_with_zero_constant(double %mag, double %a) { 1180; CHECK-LABEL: @known_positive_maybe_neg0_oge_with_zero_constant( 1181; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]]) 1182; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1183; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00 1184; CHECK-NEXT: ret i1 [[CMP]] 1185; 1186 %sqrt = call double @llvm.sqrt.f64(double %a) 1187 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1188 %cmp = fcmp oge double %copysign, 0.0 1189 ret i1 %cmp 1190} 1191 1192define i1 @known_positive_nsz_olt_with_zero_constant(double %mag, double %a) { 1193; CHECK-LABEL: @known_positive_nsz_olt_with_zero_constant( 1194; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]]) 1195; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1196; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00 1197; CHECK-NEXT: ret i1 [[CMP]] 1198; 1199 %sqrt = call nsz double @llvm.sqrt.f64(double %a) 1200 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1201 %cmp = fcmp olt double %copysign, 0.0 1202 ret i1 %cmp 1203} 1204 1205define i1 @known_positive_maybe_neg0_olt_with_zero_constant(double %mag, double %a) { 1206; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_zero_constant( 1207; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]]) 1208; CHECK-NEXT: [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]]) 1209; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00 1210; CHECK-NEXT: ret i1 [[CMP]] 1211; 1212 %sqrt = call double @llvm.sqrt.f64(double %a) 1213 %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt) 1214 %cmp = fcmp olt double %copysign, 0.0 1215 ret i1 %cmp 1216} 1217 1218define i1 @assumed_positive_olt_with_negative_constant(double %a) { 1219; CHECK-LABEL: @assumed_positive_olt_with_negative_constant( 1220; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 1221; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1222; CHECK-NEXT: ret i1 false 1223; 1224 %assume.cmp = fcmp oge double %a, 0.0 1225 call void @llvm.assume(i1 %assume.cmp) 1226 %cmp = fcmp olt double %a, -1.0 1227 ret i1 %cmp 1228} 1229 1230define i1 @assumed_positive_ole_with_negative_constant(double %a) { 1231; CHECK-LABEL: @assumed_positive_ole_with_negative_constant( 1232; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 1233; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1234; CHECK-NEXT: ret i1 false 1235; 1236 %assume.cmp = fcmp oge double %a, 0.0 1237 call void @llvm.assume(i1 %assume.cmp) 1238 %cmp = fcmp ole double %a, -1.0 1239 ret i1 %cmp 1240} 1241 1242define i1 @assumed_positive_oeq_with_negative_constant(double %a) { 1243; CHECK-LABEL: @assumed_positive_oeq_with_negative_constant( 1244; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 1245; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1246; CHECK-NEXT: ret i1 false 1247; 1248 %assume.cmp = fcmp oge double %a, 0.0 1249 call void @llvm.assume(i1 %assume.cmp) 1250 %cmp = fcmp oeq double %a, -1.0 1251 ret i1 %cmp 1252} 1253 1254define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) { 1255; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec( 1256; CHECK-NEXT: ret <2 x i1> zeroinitializer 1257; 1258 %call = uitofp <2 x i32> %a to <2 x double> 1259 %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0> 1260 ret <2 x i1> %cmp 1261} 1262 1263define i1 @known_positive_ugt_with_negative_constant(i32 %a) { 1264; CHECK-LABEL: @known_positive_ugt_with_negative_constant( 1265; CHECK-NEXT: ret i1 true 1266; 1267 %call = uitofp i32 %a to float 1268 %cmp = fcmp ugt float %call, -3.0 1269 ret i1 %cmp 1270} 1271 1272define i1 @assumed_positive_ugt_with_negative_constant(float %a) { 1273; CHECK-LABEL: @assumed_positive_ugt_with_negative_constant( 1274; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00 1275; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1276; CHECK-NEXT: ret i1 true 1277; 1278 %assume.cmp = fcmp ogt float %a, 0.0 1279 call void @llvm.assume(i1 %assume.cmp) 1280 %cmp = fcmp ugt float %a, -3.0 1281 ret i1 %cmp 1282} 1283 1284define i1 @assumed_positive_uge_with_negative_constant(float %a) { 1285; CHECK-LABEL: @assumed_positive_uge_with_negative_constant( 1286; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00 1287; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1288; CHECK-NEXT: ret i1 true 1289; 1290 %assume.cmp = fcmp ogt float %a, 0.0 1291 call void @llvm.assume(i1 %assume.cmp) 1292 %cmp = fcmp uge float %a, -3.0 1293 ret i1 %cmp 1294} 1295 1296define i1 @assumed_positive_une_with_negative_constant(float %a) { 1297; CHECK-LABEL: @assumed_positive_une_with_negative_constant( 1298; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00 1299; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1300; CHECK-NEXT: ret i1 true 1301; 1302 %assume.cmp = fcmp ogt float %a, 0.0 1303 call void @llvm.assume(i1 %assume.cmp) 1304 %cmp = fcmp une float %a, -3.0 1305 ret i1 %cmp 1306} 1307 1308define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) { 1309; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec( 1310; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1311; 1312 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 1313 %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0> 1314 ret <2 x i1> %cmp 1315} 1316 1317define i1 @known_positive_oeq_with_negative_constant(half %a) { 1318; CHECK-LABEL: @known_positive_oeq_with_negative_constant( 1319; CHECK-NEXT: ret i1 false 1320; 1321 %call = call half @llvm.fabs.f16(half %a) 1322 %cmp = fcmp oeq half %call, -5.0 1323 ret i1 %cmp 1324} 1325 1326define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) { 1327; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec( 1328; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1329; 1330 %call = uitofp <2 x i32> %a to <2 x half> 1331 %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0> 1332 ret <2 x i1> %cmp 1333} 1334 1335define i1 @pr58046(i64 %arg) { 1336; CHECK-LABEL: @pr58046( 1337; CHECK-NEXT: ret i1 true 1338; 1339 %fp = uitofp i64 %arg to double 1340 %mul = fmul double -0.000000e+00, %fp 1341 %div = fdiv double 1.000000e+00, %mul 1342 %cmp = fcmp oeq double %div, 0xFFF0000000000000 1343 ret i1 %cmp 1344} 1345 1346define i1 @nonans1(double %in1, double %in2) { 1347; CHECK-LABEL: @nonans1( 1348; CHECK-NEXT: ret i1 false 1349; 1350 %cmp = fcmp nnan uno double %in1, %in2 1351 ret i1 %cmp 1352} 1353 1354define i1 @nonans2(double %in1, double %in2) { 1355; CHECK-LABEL: @nonans2( 1356; CHECK-NEXT: ret i1 true 1357; 1358 %cmp = fcmp nnan ord double %in1, %in2 1359 ret i1 %cmp 1360} 1361 1362define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) { 1363; CHECK-LABEL: @orderedCompareWithNaNVector( 1364; CHECK-NEXT: ret <2 x i1> zeroinitializer 1365; 1366 %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF> 1367 ret <2 x i1> %cmp 1368} 1369 1370define <2 x i1> @orderedCompareWithNaNVector_poison_elt(<2 x double> %A) { 1371; CHECK-LABEL: @orderedCompareWithNaNVector_poison_elt( 1372; CHECK-NEXT: ret <2 x i1> zeroinitializer 1373; 1374 %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double poison> 1375 ret <2 x i1> %cmp 1376} 1377 1378define <2 x i1> @unorderedCompareWithNaNVector_poison_elt(<2 x double> %A) { 1379; CHECK-LABEL: @unorderedCompareWithNaNVector_poison_elt( 1380; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1381; 1382 %cmp = fcmp ult <2 x double> %A, <double poison, double 0xFFFFFFFFFFFFFFFF> 1383 ret <2 x i1> %cmp 1384} 1385 1386define i1 @is_infinite(float %x) { 1387; CHECK-LABEL: @is_infinite( 1388; CHECK-NEXT: ret i1 false 1389; 1390 %xabs = call ninf float @llvm.fabs.f32(float %x) 1391 %r = fcmp oeq float %xabs, 0x7FF0000000000000 1392 ret i1 %r 1393} 1394 1395define i1 @is_infinite_assumed_finite(float %x) { 1396; CHECK-LABEL: @is_infinite_assumed_finite( 1397; CHECK-NEXT: [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1398; CHECK-NEXT: [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000 1399; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 1400; CHECK-NEXT: ret i1 false 1401; 1402 %xabs = call float @llvm.fabs.f32(float %x) 1403 %not.inf = fcmp one float %xabs, 0x7FF0000000000000 1404 call void @llvm.assume(i1 %not.inf) 1405 %r = fcmp oeq float %xabs, 0x7FF0000000000000 1406 ret i1 %r 1407} 1408 1409define i1 @une_inf_assumed_not_inf(float %x) { 1410; CHECK-LABEL: @une_inf_assumed_not_inf( 1411; CHECK-NEXT: [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1412; CHECK-NEXT: [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000 1413; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 1414; CHECK-NEXT: ret i1 true 1415; 1416 %xabs = call float @llvm.fabs.f32(float %x) 1417 %not.inf = fcmp one float %xabs, 0x7FF0000000000000 1418 call void @llvm.assume(i1 %not.inf) 1419 %r = fcmp une float %xabs, 0x7FF0000000000000 1420 ret i1 %r 1421} 1422 1423define <2 x i1> @is_infinite_neg(<2 x float> %x) { 1424; CHECK-LABEL: @is_infinite_neg( 1425; CHECK-NEXT: ret <2 x i1> zeroinitializer 1426; 1427 %x42 = fadd ninf <2 x float> %x, <float 42.0, float 42.0> 1428 %r = fcmp oeq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000> 1429 ret <2 x i1> %r 1430} 1431 1432; Negative test - but this could be reduced to 'uno' outside of instsimplify. 1433 1434define i1 @is_infinite_or_nan(float %x) { 1435; CHECK-LABEL: @is_infinite_or_nan( 1436; CHECK-NEXT: [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01 1437; CHECK-NEXT: [[R:%.*]] = fcmp ueq float [[X42]], 0xFFF0000000000000 1438; CHECK-NEXT: ret i1 [[R]] 1439; 1440 %x42 = fadd ninf float %x, 42.0 1441 %r = fcmp ueq float %x42, 0xFFF0000000000000 1442 ret i1 %r 1443} 1444 1445define i1 @is_infinite_or_nan2(float %x) { 1446; CHECK-LABEL: @is_infinite_or_nan2( 1447; CHECK-NEXT: ret i1 false 1448; 1449 %xabs = call nnan ninf float @llvm.fabs.f32(float %x) 1450 %r = fcmp ueq float %xabs, 0x7FF0000000000000 1451 ret i1 %r 1452} 1453 1454define i1 @is_infinite_or_nan2_assume(float %x) { 1455; CHECK-LABEL: @is_infinite_or_nan2_assume( 1456; CHECK-NEXT: [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1457; CHECK-NEXT: [[IS_INF_OR_NAN:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000 1458; CHECK-NEXT: call void @llvm.assume(i1 [[IS_INF_OR_NAN]]) 1459; CHECK-NEXT: ret i1 false 1460; 1461 %xabs = call float @llvm.fabs.f32(float %x) 1462 %is.inf.or.nan = fcmp one float %xabs, 0x7FF0000000000000 1463 call void @llvm.assume(i1 %is.inf.or.nan) 1464 %r = fcmp ueq float %xabs, 0x7FF0000000000000 1465 ret i1 %r 1466} 1467 1468define <2 x i1> @is_infinite_neg_or_nan(<2 x float> %x) { 1469; CHECK-LABEL: @is_infinite_neg_or_nan( 1470; CHECK-NEXT: ret <2 x i1> zeroinitializer 1471; 1472 %x42 = fadd nnan ninf <2 x float> %x, <float 42.0, float 42.0> 1473 %r = fcmp ueq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000> 1474 ret <2 x i1> %r 1475} 1476 1477define i1 @is_finite_or_nan(i1 %c, double %x) { 1478; CHECK-LABEL: @is_finite_or_nan( 1479; CHECK-NEXT: ret i1 true 1480; 1481 %xx = fmul ninf double %x, %x 1482 %s = select i1 %c, double 42.0, double %xx 1483 %r = fcmp une double %s, 0x7FF0000000000000 1484 ret i1 %r 1485} 1486 1487define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) { 1488; CHECK-LABEL: @is_finite_or_nan_commute( 1489; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1490; 1491 %cast = uitofp <2 x i8> %x to <2 x float> 1492 %r = fcmp une <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast 1493 ret <2 x i1> %r 1494} 1495 1496; Negative test - but this could be reduced to 'ord' outside of instsimplify. 1497 1498define i1 @is_finite_and_ordered(double %x) { 1499; CHECK-LABEL: @is_finite_and_ordered( 1500; CHECK-NEXT: [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]] 1501; CHECK-NEXT: [[R:%.*]] = fcmp one double [[XX]], 0x7FF0000000000000 1502; CHECK-NEXT: ret i1 [[R]] 1503; 1504 %xx = fmul ninf double %x, %x 1505 %r = fcmp one double %xx, 0x7FF0000000000000 1506 ret i1 %r 1507} 1508 1509define i1 @is_finite(i1 %c, double %x) { 1510; CHECK-LABEL: @is_finite( 1511; CHECK-NEXT: ret i1 true 1512; 1513 %xx = fmul nnan ninf double %x, %x 1514 %s = select i1 %c, double 42.0, double %xx 1515 %r = fcmp one double %s, 0x7FF0000000000000 1516 ret i1 %r 1517} 1518 1519define i1 @is_finite_assume(i1 %c, double %x) { 1520; CHECK-LABEL: @is_finite_assume( 1521; CHECK-NEXT: [[XABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]]) 1522; CHECK-NEXT: [[IS_INF_OR_NAN:%.*]] = fcmp one double [[XABS]], 0x7FF0000000000000 1523; CHECK-NEXT: call void @llvm.assume(i1 [[IS_INF_OR_NAN]]) 1524; CHECK-NEXT: ret i1 true 1525; 1526 %xabs = call double @llvm.fabs.f64(double %x) 1527 %is.inf.or.nan = fcmp one double %xabs, 0x7FF0000000000000 1528 call void @llvm.assume(i1 %is.inf.or.nan) 1529 %s = select i1 %c, double 42.0, double %x 1530 %r = fcmp one double %s, 0x7FF0000000000000 1531 ret i1 %r 1532} 1533 1534define <2 x i1> @is_finite_commute(<2 x i8> %x) { 1535; CHECK-LABEL: @is_finite_commute( 1536; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1537; 1538 %cast = uitofp <2 x i8> %x to <2 x float> 1539 %r = fcmp one <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast 1540 ret <2 x i1> %r 1541} 1542 1543define i1 @fcmp_oge_0_assumed_oge_zero(float %x) { 1544; CHECK-LABEL: @fcmp_oge_0_assumed_oge_zero( 1545; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00 1546; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1547; CHECK-NEXT: ret i1 true 1548; 1549 %assume.cmp = fcmp oge float %x, 0.0 1550 call void @llvm.assume(i1 %assume.cmp) 1551 %r = fcmp oge float %x, 0.000000e+00 1552 ret i1 %r 1553} 1554 1555define i1 @fcmp_ult_0_assumed_oge_zero(float %x) { 1556; CHECK-LABEL: @fcmp_ult_0_assumed_oge_zero( 1557; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00 1558; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1559; CHECK-NEXT: ret i1 false 1560; 1561 %assume.cmp = fcmp oge float %x, 0.0 1562 call void @llvm.assume(i1 %assume.cmp) 1563 %r = fcmp ult float %x, 0.000000e+00 1564 ret i1 %r 1565} 1566 1567define i1 @fcmp_uge_0_assumed_oge_zero(float %x) { 1568; CHECK-LABEL: @fcmp_uge_0_assumed_oge_zero( 1569; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00 1570; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1571; CHECK-NEXT: ret i1 true 1572; 1573 %assume.cmp = fcmp oge float %x, 0.0 1574 call void @llvm.assume(i1 %assume.cmp) 1575 %r = fcmp uge float %x, 0.000000e+00 1576 ret i1 %r 1577} 1578 1579define i1 @fcmp_olt_0_assumed_oge_zero(float %x) { 1580; CHECK-LABEL: @fcmp_olt_0_assumed_oge_zero( 1581; CHECK-NEXT: [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00 1582; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_CMP]]) 1583; CHECK-NEXT: ret i1 false 1584; 1585 %assume.cmp = fcmp oge float %x, 0.0 1586 call void @llvm.assume(i1 %assume.cmp) 1587 %r = fcmp olt float %x, 0.000000e+00 1588 ret i1 %r 1589} 1590 1591define i1 @ogt_zero_fabs_select_negone_or_pinf(i1 %cond) { 1592; CHECK-LABEL: @ogt_zero_fabs_select_negone_or_pinf( 1593; CHECK-NEXT: entry: 1594; CHECK-NEXT: ret i1 true 1595; 1596entry: 1597 %select = select i1 %cond, float -1.0, float 0x7FF0000000000000 1598 %fabs = call float @llvm.fabs.f32(float %select) 1599 %one = fcmp ogt float %fabs, 0.0 1600 ret i1 %one 1601} 1602 1603define i1 @ogt_zero_fabs_select_one_or_ninf(i1 %cond) { 1604; CHECK-LABEL: @ogt_zero_fabs_select_one_or_ninf( 1605; CHECK-NEXT: entry: 1606; CHECK-NEXT: ret i1 true 1607; 1608entry: 1609 %select = select i1 %cond, float 1.0, float 0xFFF0000000000000 1610 %fabs = call float @llvm.fabs.f32(float %select) 1611 %one = fcmp ogt float %fabs, 0.0 1612 ret i1 %one 1613} 1614 1615; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp 1616define float @fast_square_must_be_positive_ieee(float %arg, float %arg1) { 1617; CHECK-LABEL: @fast_square_must_be_positive_ieee( 1618; CHECK-NEXT: bb: 1619; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1620; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1621; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1622; CHECK-NEXT: ret float [[I3]] 1623; 1624bb: 1625 %i = fmul float %arg, %arg 1626 %i2 = fmul float %arg1, %arg1 1627 %i3 = fadd float %i2, %i 1628 %i4 = fcmp olt float %i3, 0.000000e+00 1629 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1630 ret float %i5 1631} 1632 1633; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp 1634define float @fast_square_must_be_positive_ieee_nnan(float %arg, float %arg1) { 1635; CHECK-LABEL: @fast_square_must_be_positive_ieee_nnan( 1636; CHECK-NEXT: bb: 1637; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1638; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1639; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1640; CHECK-NEXT: ret float [[I3]] 1641; 1642bb: 1643 %i = fmul float %arg, %arg 1644 %i2 = fmul float %arg1, %arg1 1645 %i3 = fadd float %i2, %i 1646 %i4 = fcmp nnan olt float %i3, 0.000000e+00 1647 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1648 ret float %i5 1649} 1650 1651; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp 1652define float @fast_square_must_be_positive_daz(float %arg, float %arg1) #0 { 1653; CHECK-LABEL: @fast_square_must_be_positive_daz( 1654; CHECK-NEXT: bb: 1655; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1656; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1657; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1658; CHECK-NEXT: ret float [[I3]] 1659; 1660bb: 1661 %i = fmul float %arg, %arg 1662 %i2 = fmul float %arg1, %arg1 1663 %i3 = fadd float %i2, %i 1664 %i4 = fcmp olt float %i3, 0.000000e+00 1665 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1666 ret float %i5 1667} 1668 1669; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp 1670define float @fast_square_must_be_positive_daz_nnan(float %arg, float %arg1) #0 { 1671; CHECK-LABEL: @fast_square_must_be_positive_daz_nnan( 1672; CHECK-NEXT: bb: 1673; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1674; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1675; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1676; CHECK-NEXT: ret float [[I3]] 1677; 1678bb: 1679 %i = fmul float %arg, %arg 1680 %i2 = fmul float %arg1, %arg1 1681 %i3 = fadd float %i2, %i 1682 %i4 = fcmp nnan olt float %i3, 0.000000e+00 1683 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1684 ret float %i5 1685} 1686 1687; Make the compare to negative constant is folded out 1688define float @must_be_olt_negative_constant_daz(float %arg, float %arg1) #0 { 1689; CHECK-LABEL: @must_be_olt_negative_constant_daz( 1690; CHECK-NEXT: bb: 1691; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1692; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1693; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1694; CHECK-NEXT: ret float [[I3]] 1695; 1696bb: 1697 %i = fmul float %arg, %arg 1698 %i2 = fmul float %arg1, %arg1 1699 %i3 = fadd float %i2, %i 1700 %i4 = fcmp olt float %i3, -1.0 1701 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1702 ret float %i5 1703} 1704 1705; Make the compare to negative constant is folded out 1706define float @must_be_olt_negative_constant_daz_nnan(float %arg, float %arg1) #0 { 1707; CHECK-LABEL: @must_be_olt_negative_constant_daz_nnan( 1708; CHECK-NEXT: bb: 1709; CHECK-NEXT: [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]] 1710; CHECK-NEXT: [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]] 1711; CHECK-NEXT: [[I3:%.*]] = fadd float [[I2]], [[I]] 1712; CHECK-NEXT: ret float [[I3]] 1713; 1714bb: 1715 %i = fmul float %arg, %arg 1716 %i2 = fmul float %arg1, %arg1 1717 %i3 = fadd float %i2, %i 1718 %i4 = fcmp nnan olt float %i3, -1.0 1719 %i5 = select i1 %i4, float 0.000000e+00, float %i3 1720 ret float %i5 1721} 1722 1723define i1 @is_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" { 1724; CHECK-LABEL: @is_olt_smallest_normal_dynamic( 1725; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000 1726; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1727; 1728 %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000 1729 ret i1 %is.denorm.or.zero 1730} 1731 1732define i1 @is_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" { 1733; CHECK-LABEL: @is_olt_smallest_normal_ieee( 1734; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000 1735; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1736; 1737 %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000 1738 ret i1 %is.denorm.or.zero 1739} 1740 1741define i1 @is_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" { 1742; CHECK-LABEL: @is_olt_smallest_normal_preserve_sign( 1743; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000 1744; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1745; 1746 %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000 1747 ret i1 %is.denorm.or.zero 1748} 1749 1750define i1 @is_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" { 1751; CHECK-LABEL: @is_olt_smallest_normal_positive_zero( 1752; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000 1753; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1754; 1755 %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000 1756 ret i1 %is.denorm.or.zero 1757} 1758 1759define i1 @is_fabs_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" { 1760; CHECK-LABEL: @is_fabs_olt_smallest_normal_dynamic( 1761; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1762; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000 1763; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1764; 1765 %fabs.x = call float @llvm.fabs.f32(float %x) 1766 %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000 1767 ret i1 %is.denorm.or.zero 1768} 1769 1770define i1 @is_fabs_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" { 1771; CHECK-LABEL: @is_fabs_olt_smallest_normal_ieee( 1772; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1773; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000 1774; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1775; 1776 %fabs.x = call float @llvm.fabs.f32(float %x) 1777 %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000 1778 ret i1 %is.denorm.or.zero 1779} 1780 1781define i1 @is_fabs_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" { 1782; CHECK-LABEL: @is_fabs_olt_smallest_normal_preserve_sign( 1783; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1784; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000 1785; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1786; 1787 %fabs.x = call float @llvm.fabs.f32(float %x) 1788 %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000 1789 ret i1 %is.denorm.or.zero 1790} 1791 1792define i1 @is_fabs_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" { 1793; CHECK-LABEL: @is_fabs_olt_smallest_normal_positive_zero( 1794; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 1795; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000 1796; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]] 1797; 1798 %fabs.x = call float @llvm.fabs.f32(float %x) 1799 %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000 1800 ret i1 %is.denorm.or.zero 1801} 1802 1803 1804declare <2 x double> @llvm.fabs.v2f64(<2 x double>) 1805declare <2 x float> @llvm.fabs.v2f32(<2 x float>) 1806declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>) 1807declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>) 1808declare <3 x float> @llvm.fabs.v3f32(<3 x float>) 1809declare double @llvm.exp2.f64(double) 1810declare double @llvm.fabs.f64(double) 1811declare double @llvm.powi.f64.i32(double, i32) 1812declare float @llvm.exp.f32(float) 1813declare float @llvm.fabs.f32(float) 1814declare float @llvm.fma.f32(float, float, float) 1815declare float @llvm.maximum.f32(float, float) 1816declare float @llvm.maxnum.f32(float, float) 1817declare float @llvm.minnum.f32(float, float) 1818declare float @llvm.sqrt.f32(float) 1819declare double @llvm.sqrt.f64(double) 1820declare double @llvm.copysign.f64(double, double) 1821declare half @llvm.fabs.f16(half) 1822declare void @llvm.assume(i1 noundef) 1823 1824attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" } 1825