1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare half @llvm.fabs.f16(half) 5declare double @llvm.fabs.f64(double) 6declare <2 x float> @llvm.fabs.v2f32(<2 x float>) 7declare double @llvm.copysign.f64(double, double) 8declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>) 9 10declare void @use(float) 11 12define i1 @fpext_fpext(float %x, float %y) { 13; CHECK-LABEL: @fpext_fpext( 14; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 15; CHECK-NEXT: ret i1 [[CMP]] 16; 17 %ext1 = fpext float %x to double 18 %ext2 = fpext float %y to double 19 %cmp = fcmp nnan ogt double %ext1, %ext2 20 ret i1 %cmp 21} 22 23define i1 @fpext_constant(float %a) { 24; CHECK-LABEL: @fpext_constant( 25; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[A:%.*]], 1.000000e+00 26; CHECK-NEXT: ret i1 [[CMP]] 27; 28 %ext = fpext float %a to double 29 %cmp = fcmp ninf ogt double %ext, 1.000000e+00 30 ret i1 %cmp 31} 32 33define <2 x i1> @fpext_constant_vec_splat(<2 x half> %a) { 34; CHECK-LABEL: @fpext_constant_vec_splat( 35; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ole <2 x half> [[A:%.*]], splat (half 0xH5140) 36; CHECK-NEXT: ret <2 x i1> [[CMP]] 37; 38 %ext = fpext <2 x half> %a to <2 x double> 39 %cmp = fcmp nnan ole <2 x double> %ext, <double 42.0, double 42.0> 40 ret <2 x i1> %cmp 41} 42 43define i1 @fpext_constant_lossy(float %a) { 44; CHECK-LABEL: @fpext_constant_lossy( 45; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double 46; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001 47; CHECK-NEXT: ret i1 [[CMP]] 48; 49 %ext = fpext float %a to double 50 %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float. 51 ret i1 %cmp 52} 53 54define i1 @fpext_constant_denorm(float %a) { 55; CHECK-LABEL: @fpext_constant_denorm( 56; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double 57; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000 58; CHECK-NEXT: ret i1 [[CMP]] 59; 60 %ext = fpext float %a to double 61 %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float. 62 ret i1 %cmp 63} 64 65define i1 @fneg_constant_swap_pred(float %x) { 66; CHECK-LABEL: @fneg_constant_swap_pred( 67; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00 68; CHECK-NEXT: ret i1 [[CMP]] 69; 70 %neg = fsub float -0.0, %x 71 %cmp = fcmp ogt float %neg, 1.0 72 ret i1 %cmp 73} 74 75define i1 @unary_fneg_constant_swap_pred(float %x) { 76; CHECK-LABEL: @unary_fneg_constant_swap_pred( 77; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00 78; CHECK-NEXT: ret i1 [[CMP]] 79; 80 %neg = fneg float %x 81 %cmp = fcmp ogt float %neg, 1.0 82 ret i1 %cmp 83} 84 85define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) { 86; CHECK-LABEL: @fneg_constant_swap_pred_vec( 87; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00> 88; CHECK-NEXT: ret <2 x i1> [[CMP]] 89; 90 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x 91 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0> 92 ret <2 x i1> %cmp 93} 94 95define <2 x i1> @unary_fneg_constant_swap_pred_vec(<2 x float> %x) { 96; CHECK-LABEL: @unary_fneg_constant_swap_pred_vec( 97; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00> 98; CHECK-NEXT: ret <2 x i1> [[CMP]] 99; 100 %neg = fneg <2 x float> %x 101 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0> 102 ret <2 x i1> %cmp 103} 104 105define <2 x i1> @fneg_constant_swap_pred_vec_poison(<2 x float> %x) { 106; CHECK-LABEL: @fneg_constant_swap_pred_vec_poison( 107; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00> 108; CHECK-NEXT: ret <2 x i1> [[CMP]] 109; 110 %neg = fsub <2 x float> <float poison, float -0.0>, %x 111 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0> 112 ret <2 x i1> %cmp 113} 114 115; The new fcmp should have the same FMF as the original. 116 117define i1 @fneg_fmf(float %x) { 118; CHECK-LABEL: @fneg_fmf( 119; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01 120; CHECK-NEXT: ret i1 [[R]] 121; 122 %n = fsub fast float -0.0, %x 123 %r = fcmp fast oeq float %n, 42.0 124 ret i1 %r 125} 126 127define i1 @unary_fneg_fmf(float %x) { 128; CHECK-LABEL: @unary_fneg_fmf( 129; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01 130; CHECK-NEXT: ret i1 [[R]] 131; 132 %n = fneg fast float %x 133 %r = fcmp fast oeq float %n, 42.0 134 ret i1 %r 135} 136 137; The new fcmp should have the same FMF as the original, vector edition. 138 139define <2 x i1> @fcmp_fneg_fmf_vec(<2 x float> %x) { 140; CHECK-LABEL: @fcmp_fneg_fmf_vec( 141; CHECK-NEXT: [[R:%.*]] = fcmp reassoc nnan ule <2 x float> [[X:%.*]], <float -4.200000e+01, float 1.900000e+01> 142; CHECK-NEXT: ret <2 x i1> [[R]] 143; 144 %n = fsub nsz <2 x float> zeroinitializer, %x 145 %r = fcmp nnan reassoc uge <2 x float> %n, <float 42.0, float -19.0> 146 ret <2 x i1> %r 147} 148 149define i1 @fneg_fneg_swap_pred(float %x, float %y) { 150; CHECK-LABEL: @fneg_fneg_swap_pred( 151; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 152; CHECK-NEXT: ret i1 [[CMP]] 153; 154 %neg1 = fsub float -0.0, %x 155 %neg2 = fsub float -0.0, %y 156 %cmp = fcmp nnan olt float %neg1, %neg2 157 ret i1 %cmp 158} 159 160define i1 @unary_fneg_unary_fneg_swap_pred(float %x, float %y) { 161; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred( 162; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 163; CHECK-NEXT: ret i1 [[CMP]] 164; 165 %neg1 = fneg float %x 166 %neg2 = fneg float %y 167 %cmp = fcmp nnan olt float %neg1, %neg2 168 ret i1 %cmp 169} 170 171define i1 @unary_fneg_fneg_swap_pred(float %x, float %y) { 172; CHECK-LABEL: @unary_fneg_fneg_swap_pred( 173; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 174; CHECK-NEXT: ret i1 [[CMP]] 175; 176 %neg1 = fneg float %x 177 %neg2 = fsub float -0.0, %y 178 %cmp = fcmp nnan olt float %neg1, %neg2 179 ret i1 %cmp 180} 181 182define i1 @fneg_unary_fneg_swap_pred(float %x, float %y) { 183; CHECK-LABEL: @fneg_unary_fneg_swap_pred( 184; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 185; CHECK-NEXT: ret i1 [[CMP]] 186; 187 %neg1 = fsub float -0.0, %x 188 %neg2 = fneg float %y 189 %cmp = fcmp nnan olt float %neg1, %neg2 190 ret i1 %cmp 191} 192 193define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) { 194; CHECK-LABEL: @fneg_fneg_swap_pred_vec( 195; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]] 196; CHECK-NEXT: ret <2 x i1> [[CMP]] 197; 198 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x 199 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y 200 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2 201 ret <2 x i1> %cmp 202} 203 204define <2 x i1> @unary_fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) { 205; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred_vec( 206; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]] 207; CHECK-NEXT: ret <2 x i1> [[CMP]] 208; 209 %neg1 = fneg <2 x float> %x 210 %neg2 = fneg <2 x float> %y 211 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2 212 ret <2 x i1> %cmp 213} 214 215define <2 x i1> @unary_fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) { 216; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec( 217; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]] 218; CHECK-NEXT: ret <2 x i1> [[CMP]] 219; 220 %neg1 = fneg <2 x float> %x 221 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y 222 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2 223 ret <2 x i1> %cmp 224} 225 226define <2 x i1> @fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) { 227; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec( 228; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]] 229; CHECK-NEXT: ret <2 x i1> [[CMP]] 230; 231 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x 232 %neg2 = fneg <2 x float> %y 233 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2 234 ret <2 x i1> %cmp 235} 236 237define <2 x i1> @fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) { 238; CHECK-LABEL: @fneg_fneg_swap_pred_vec_poison( 239; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]] 240; CHECK-NEXT: ret <2 x i1> [[CMP]] 241; 242 %neg1 = fsub <2 x float> <float -0.0, float poison>, %x 243 %neg2 = fsub <2 x float> <float poison, float -0.0>, %y 244 %cmp = fcmp olt <2 x float> %neg1, %neg2 245 ret <2 x i1> %cmp 246} 247 248define <2 x i1> @unary_fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) { 249; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec_poison( 250; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]] 251; CHECK-NEXT: ret <2 x i1> [[CMP]] 252; 253 %neg1 = fneg <2 x float> %x 254 %neg2 = fsub <2 x float> <float poison, float -0.0>, %y 255 %cmp = fcmp olt <2 x float> %neg1, %neg2 256 ret <2 x i1> %cmp 257} 258 259define <2 x i1> @fneg_unary_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) { 260; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec_poison( 261; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]] 262; CHECK-NEXT: ret <2 x i1> [[CMP]] 263; 264 %neg1 = fsub <2 x float> <float -0.0, float poison>, %x 265 %neg2 = fneg <2 x float> %y 266 %cmp = fcmp olt <2 x float> %neg1, %neg2 267 ret <2 x i1> %cmp 268} 269 270define i1 @test7(float %x) { 271; CHECK-LABEL: @test7( 272; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00 273; CHECK-NEXT: ret i1 [[CMP]] 274; 275 %ext = fpext float %x to ppc_fp128 276 %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000 277 ret i1 %cmp 278} 279 280define float @test8(float %x) { 281; CHECK-LABEL: @test8( 282; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00 283; CHECK-NEXT: [[CONV2:%.*]] = uitofp i1 [[CMP]] to float 284; CHECK-NEXT: ret float [[CONV2]] 285; 286 %conv = fpext float %x to double 287 %cmp = fcmp olt double %conv, 0.000000e+00 288 %conv1 = zext i1 %cmp to i32 289 %conv2 = sitofp i32 %conv1 to float 290 ret float %conv2 291; Float comparison to zero shouldn't cast to double. 292} 293 294define i1 @fabs_uge(double %a) { 295; CHECK-LABEL: @fabs_uge( 296; CHECK-NEXT: ret i1 true 297; 298 %call = call double @llvm.fabs.f64(double %a) 299 %cmp = fcmp uge double %call, 0.0 300 ret i1 %cmp 301} 302 303define i1 @fabs_olt(half %a) { 304; CHECK-LABEL: @fabs_olt( 305; CHECK-NEXT: ret i1 false 306; 307 %call = call half @llvm.fabs.f16(half %a) 308 %cmp = fcmp olt half %call, 0.0 309 ret i1 %cmp 310} 311 312define <2 x i1> @fabs_ole(<2 x float> %a) { 313; CHECK-LABEL: @fabs_ole( 314; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq <2 x float> [[A:%.*]], zeroinitializer 315; CHECK-NEXT: ret <2 x i1> [[CMP]] 316; 317 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 318 %cmp = fcmp ninf ole <2 x float> %call, zeroinitializer 319 ret <2 x i1> %cmp 320} 321 322define <2 x i1> @fabs_ule(<2 x float> %a) { 323; CHECK-LABEL: @fabs_ule( 324; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf arcp ueq <2 x float> [[A:%.*]], zeroinitializer 325; CHECK-NEXT: ret <2 x i1> [[CMP]] 326; 327 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 328 %cmp = fcmp ninf arcp ule <2 x float> %call, zeroinitializer 329 ret <2 x i1> %cmp 330} 331 332define i1 @fabs_ogt(double %a) { 333; CHECK-LABEL: @fabs_ogt( 334; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc one double [[A:%.*]], 0.000000e+00 335; CHECK-NEXT: ret i1 [[CMP]] 336; 337 %call = call double @llvm.fabs.f64(double %a) 338 %cmp = fcmp reassoc ogt double %call, 0.0 339 ret i1 %cmp 340} 341 342define i1 @fabs_ugt(double %a) { 343; CHECK-LABEL: @fabs_ugt( 344; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf une double [[A:%.*]], 0.000000e+00 345; CHECK-NEXT: ret i1 [[CMP]] 346; 347 %call = call double @llvm.fabs.f64(double %a) 348 %cmp = fcmp ninf reassoc ugt double %call, 0.0 349 ret i1 %cmp 350} 351 352define i1 @fabs_oge(double %a) { 353; CHECK-LABEL: @fabs_oge( 354; CHECK-NEXT: [[CMP:%.*]] = fcmp afn ord double [[A:%.*]], 0.000000e+00 355; CHECK-NEXT: ret i1 [[CMP]] 356; 357 %call = call double @llvm.fabs.f64(double %a) 358 %cmp = fcmp afn oge double %call, 0.0 359 ret i1 %cmp 360} 361 362define i1 @fabs_ult(double %a) { 363; CHECK-LABEL: @fabs_ult( 364; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc arcp uno double [[A:%.*]], 0.000000e+00 365; CHECK-NEXT: ret i1 [[CMP]] 366; 367 %call = call double @llvm.fabs.f64(double %a) 368 %cmp = fcmp reassoc arcp ult double %call, 0.0 369 ret i1 %cmp 370} 371 372define <2 x i1> @fabs_ult_nnan(<2 x float> %a) { 373; CHECK-LABEL: @fabs_ult_nnan( 374; CHECK-NEXT: ret <2 x i1> zeroinitializer 375; 376 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 377 %cmp = fcmp nnan reassoc arcp ult <2 x float> %call, zeroinitializer 378 ret <2 x i1> %cmp 379} 380 381define i1 @fabs_une(half %a) { 382; CHECK-LABEL: @fabs_une( 383; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une half [[A:%.*]], 0xH0000 384; CHECK-NEXT: ret i1 [[CMP]] 385; 386 %call = call half @llvm.fabs.f16(half %a) 387 %cmp = fcmp ninf une half %call, 0.0 388 ret i1 %cmp 389} 390 391define i1 @fabs_oeq(double %a) { 392; CHECK-LABEL: @fabs_oeq( 393; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf oeq double [[A:%.*]], 0.000000e+00 394; CHECK-NEXT: ret i1 [[CMP]] 395; 396 %call = call double @llvm.fabs.f64(double %a) 397 %cmp = fcmp ninf reassoc oeq double %call, 0.0 398 ret i1 %cmp 399} 400 401define i1 @fabs_one(double %a) { 402; CHECK-LABEL: @fabs_one( 403; CHECK-NEXT: [[CMP:%.*]] = fcmp fast one double [[A:%.*]], 0.000000e+00 404; CHECK-NEXT: ret i1 [[CMP]] 405; 406 %call = call double @llvm.fabs.f64(double %a) 407 %cmp = fcmp fast one double %call, 0.0 408 ret i1 %cmp 409} 410 411define <2 x i1> @fabs_ueq(<2 x float> %a) { 412; CHECK-LABEL: @fabs_ueq( 413; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ueq <2 x float> [[A:%.*]], zeroinitializer 414; CHECK-NEXT: ret <2 x i1> [[CMP]] 415; 416 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 417 %cmp = fcmp arcp ueq <2 x float> %call, zeroinitializer 418 ret <2 x i1> %cmp 419} 420 421define <2 x i1> @fabs_ord(<2 x float> %a) { 422; CHECK-LABEL: @fabs_ord( 423; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ord <2 x float> [[A:%.*]], zeroinitializer 424; CHECK-NEXT: ret <2 x i1> [[CMP]] 425; 426 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 427 %cmp = fcmp arcp ord <2 x float> %call, zeroinitializer 428 ret <2 x i1> %cmp 429} 430 431define <2 x i1> @fabs_uno(<2 x float> %a) { 432; CHECK-LABEL: @fabs_uno( 433; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp uno <2 x float> [[A:%.*]], zeroinitializer 434; CHECK-NEXT: ret <2 x i1> [[CMP]] 435; 436 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a) 437 %cmp = fcmp arcp uno <2 x float> %call, zeroinitializer 438 ret <2 x i1> %cmp 439} 440 441; Don't crash. 442define i32 @test17(double %a, ptr %p) { 443; CHECK-LABEL: @test17( 444; CHECK-NEXT: [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]]) 445; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00 446; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 447; CHECK-NEXT: ret i32 [[CONV]] 448; 449 %call = tail call double %p(double %a) 450 %cmp = fcmp ueq double %call, 0.000000e+00 451 %conv = zext i1 %cmp to i32 452 ret i32 %conv 453} 454 455; Can fold fcmp with undef on one side by choosing NaN for the undef 456define i32 @test18_undef_unordered(float %a) { 457; CHECK-LABEL: @test18_undef_unordered( 458; CHECK-NEXT: ret i32 1 459; 460 %cmp = fcmp ueq float %a, undef 461 %conv = zext i1 %cmp to i32 462 ret i32 %conv 463} 464; Can fold fcmp with undef on one side by choosing NaN for the undef 465define i32 @test18_undef_ordered(float %a) { 466; CHECK-LABEL: @test18_undef_ordered( 467; CHECK-NEXT: ret i32 0 468; 469 %cmp = fcmp oeq float %a, undef 470 %conv = zext i1 %cmp to i32 471 ret i32 %conv 472} 473 474; Can fold fcmp with undef on both side 475; fcmp u_pred undef, undef -> true 476; fcmp o_pred undef, undef -> false 477; because whatever you choose for the first undef 478; you can choose NaN for the other undef 479define i1 @test19_undef_unordered() { 480; CHECK-LABEL: @test19_undef_unordered( 481; CHECK-NEXT: ret i1 true 482; 483 %cmp = fcmp ueq float undef, undef 484 ret i1 %cmp 485} 486 487define i1 @test19_undef_ordered() { 488; CHECK-LABEL: @test19_undef_ordered( 489; CHECK-NEXT: ret i1 false 490; 491 %cmp = fcmp oeq float undef, undef 492 ret i1 %cmp 493} 494 495; Can fold 1.0 / X < 0.0 --> X < 0 with ninf 496define i1 @test20_recipX_olt_0(float %X) { 497; CHECK-LABEL: @test20_recipX_olt_0( 498; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt float [[X:%.*]], 0.000000e+00 499; CHECK-NEXT: ret i1 [[CMP]] 500; 501 %div = fdiv ninf float 1.0, %X 502 %cmp = fcmp ninf olt float %div, 0.0 503 ret i1 %cmp 504} 505 506; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf 507define i1 @test21_recipX_ole_0(float %X) { 508; CHECK-LABEL: @test21_recipX_ole_0( 509; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oge float [[X:%.*]], 0.000000e+00 510; CHECK-NEXT: ret i1 [[CMP]] 511; 512 %div = fdiv ninf float -2.0, %X 513 %cmp = fcmp ninf ole float %div, 0.0 514 ret i1 %cmp 515} 516 517; Can fold 2.0 / X > 0.0 --> X > 0 with ninf 518define i1 @test22_recipX_ogt_0(float %X) { 519; CHECK-LABEL: @test22_recipX_ogt_0( 520; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[X:%.*]], 0.000000e+00 521; CHECK-NEXT: ret i1 [[CMP]] 522; 523 %div = fdiv ninf float 2.0, %X 524 %cmp = fcmp ninf ogt float %div, 0.0 525 ret i1 %cmp 526} 527 528; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf 529define i1 @test23_recipX_oge_0(float %X) { 530; CHECK-LABEL: @test23_recipX_oge_0( 531; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ole float [[X:%.*]], 0.000000e+00 532; CHECK-NEXT: ret i1 [[CMP]] 533; 534 %div = fdiv ninf float -1.0, %X 535 %cmp = fcmp ninf oge float %div, 0.0 536 ret i1 %cmp 537} 538 539; Do not fold 1.0 / X > 0.0 when ninf is missing 540define i1 @test24_recipX_noninf_cmp(float %X) { 541; CHECK-LABEL: @test24_recipX_noninf_cmp( 542; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]] 543; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[DIV]], 0.000000e+00 544; CHECK-NEXT: ret i1 [[CMP]] 545; 546 %div = fdiv ninf float 2.0, %X 547 %cmp = fcmp ogt float %div, 0.0 548 ret i1 %cmp 549} 550 551; Do not fold 1.0 / X > 0.0 when ninf is missing 552define i1 @test25_recipX_noninf_div(float %X) { 553; CHECK-LABEL: @test25_recipX_noninf_div( 554; CHECK-NEXT: [[DIV:%.*]] = fdiv float 2.000000e+00, [[X:%.*]] 555; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[DIV]], 0.000000e+00 556; CHECK-NEXT: ret i1 [[CMP]] 557; 558 %div = fdiv float 2.0, %X 559 %cmp = fcmp ninf ogt float %div, 0.0 560 ret i1 %cmp 561} 562 563; Do not fold 1.0 / X > 0.0 with unordered predicates 564define i1 @test26_recipX_unorderd(float %X) { 565; CHECK-LABEL: @test26_recipX_unorderd( 566; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]] 567; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ugt float [[DIV]], 0.000000e+00 568; CHECK-NEXT: ret i1 [[CMP]] 569; 570 %div = fdiv ninf float 2.0, %X 571 %cmp = fcmp ninf ugt float %div, 0.0 572 ret i1 %cmp 573} 574 575; Fold <-1.0, -1.0> / X > <-0.0, -0.0> 576define <2 x i1> @test27_recipX_gt_vecsplat(<2 x float> %X) { 577; CHECK-LABEL: @test27_recipX_gt_vecsplat( 578; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer 579; CHECK-NEXT: ret <2 x i1> [[CMP]] 580; 581 %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X 582 %cmp = fcmp ninf ogt <2 x float> %div, <float -0.0, float -0.0> 583 ret <2 x i1> %cmp 584} 585 586define i1 @is_signbit_set(double %x) { 587; CHECK-LABEL: @is_signbit_set( 588; CHECK-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 589; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[TMP1]], 0 590; CHECK-NEXT: ret i1 [[R]] 591; 592 %s = call double @llvm.copysign.f64(double 1.0, double %x) 593 %r = fcmp olt double %s, 0.0 594 ret i1 %r 595} 596 597define i1 @is_signbit_set_1(double %x) { 598; CHECK-LABEL: @is_signbit_set_1( 599; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 600; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[S]], 0.000000e+00 601; CHECK-NEXT: ret i1 [[R]] 602; 603 %s = call double @llvm.copysign.f64(double 1.0, double %x) 604 %r = fcmp ult double %s, 0.0 605 ret i1 %r 606} 607 608define i1 @is_signbit_set_2(double %x) { 609; CHECK-LABEL: @is_signbit_set_2( 610; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 611; CHECK-NEXT: [[R:%.*]] = fcmp ole double [[S]], 0.000000e+00 612; CHECK-NEXT: ret i1 [[R]] 613; 614 %s = call double @llvm.copysign.f64(double 1.0, double %x) 615 %r = fcmp ole double %s, 0.0 616 ret i1 %r 617} 618 619define i1 @is_signbit_set_3(double %x) { 620; CHECK-LABEL: @is_signbit_set_3( 621; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 622; CHECK-NEXT: [[R:%.*]] = fcmp ule double [[S]], 0.000000e+00 623; CHECK-NEXT: ret i1 [[R]] 624; 625 %s = call double @llvm.copysign.f64(double 1.0, double %x) 626 %r = fcmp ule double %s, 0.0 627 ret i1 %r 628} 629 630; Vectors are ok; the sign of zero in the compare doesn't matter; the copysign constant can be any non-zero number. 631 632define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) { 633; CHECK-LABEL: @is_signbit_set_anyzero( 634; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64> 635; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i64> [[TMP1]], zeroinitializer 636; CHECK-NEXT: ret <2 x i1> [[R]] 637; 638 %s = call <2 x double> @llvm.copysign.v2f64(<2 x double> <double 42.0, double 42.0>, <2 x double> %x) 639 %r = fcmp olt <2 x double> %s, <double -0.0, double 0.0> 640 ret <2 x i1> %r 641} 642 643; TODO: Handle different predicates. 644 645define i1 @is_signbit_clear(double %x) { 646; CHECK-LABEL: @is_signbit_clear( 647; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) 648; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00 649; CHECK-NEXT: ret i1 [[R]] 650; 651 %s = call double @llvm.copysign.f64(double -42.0, double %x) 652 %r = fcmp ogt double %s, 0.0 653 ret i1 %r 654} 655 656define i1 @is_signbit_clear_1(double %x) { 657; CHECK-LABEL: @is_signbit_clear_1( 658; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) 659; CHECK-NEXT: [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00 660; CHECK-NEXT: ret i1 [[R]] 661; 662 %s = call double @llvm.copysign.f64(double -42.0, double %x) 663 %r = fcmp ugt double %s, 0.0 664 ret i1 %r 665} 666 667define i1 @is_signbit_clear_2(double %x) { 668; CHECK-LABEL: @is_signbit_clear_2( 669; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) 670; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00 671; CHECK-NEXT: ret i1 [[R]] 672; 673 %s = call double @llvm.copysign.f64(double -42.0, double %x) 674 %r = fcmp oge double %s, 0.0 675 ret i1 %r 676} 677 678define i1 @is_signbit_clear_3(double %x) { 679; CHECK-LABEL: @is_signbit_clear_3( 680; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) 681; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00 682; CHECK-NEXT: ret i1 [[R]] 683; 684 %s = call double @llvm.copysign.f64(double -42.0, double %x) 685 %r = fcmp uge double %s, 0.0 686 ret i1 %r 687} 688 689; Negative test - uses 690 691define i1 @is_signbit_set_extra_use(double %x, ptr %p) { 692; CHECK-LABEL: @is_signbit_set_extra_use( 693; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 694; CHECK-NEXT: store double [[S]], ptr [[P:%.*]], align 8 695; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[S]], 0.000000e+00 696; CHECK-NEXT: ret i1 [[R]] 697; 698 %s = call double @llvm.copysign.f64(double 1.0, double %x) 699 store double %s, ptr %p 700 %r = fcmp olt double %s, 0.0 701 ret i1 %r 702} 703 704; TODO: Handle non-zero compare constant. 705 706define i1 @is_signbit_clear_nonzero(double %x) { 707; CHECK-LABEL: @is_signbit_clear_nonzero( 708; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) 709; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00 710; CHECK-NEXT: ret i1 [[R]] 711; 712 %s = call double @llvm.copysign.f64(double -42.0, double %x) 713 %r = fcmp ogt double %s, 1.0 714 ret i1 %r 715} 716 717; TODO: Handle zero copysign constant. 718 719define i1 @is_signbit_set_simplify_zero(double %x) { 720; CHECK-LABEL: @is_signbit_set_simplify_zero( 721; CHECK-NEXT: ret i1 false 722; 723 %s = call double @llvm.copysign.f64(double 0.0, double %x) 724 %r = fcmp ogt double %s, 0.0 725 ret i1 %r 726} 727 728; TODO: Handle NaN copysign constant. 729 730define i1 @is_signbit_set_simplify_nan(double %x) { 731; CHECK-LABEL: @is_signbit_set_simplify_nan( 732; CHECK-NEXT: ret i1 false 733; 734 %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x) 735 %r = fcmp ogt double %s, 0.0 736 ret i1 %r 737} 738 739define <2 x i1> @lossy_oeq(<2 x float> %x) { 740; CHECK-LABEL: @lossy_oeq( 741; CHECK-NEXT: ret <2 x i1> zeroinitializer 742; 743 %e = fpext <2 x float> %x to <2 x double> 744 %r = fcmp oeq <2 x double> %e, <double 0.1, double 0.1> 745 ret <2 x i1> %r 746} 747 748define i1 @lossy_one(float %x, ptr %p) { 749; CHECK-LABEL: @lossy_one( 750; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double 751; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8 752; CHECK-NEXT: [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00 753; CHECK-NEXT: ret i1 [[R]] 754; 755 %e = fpext float %x to double 756 store double %e, ptr %p 757 %r = fcmp one double %e, 0.1 758 ret i1 %r 759} 760 761define i1 @lossy_ueq(half %x) { 762; CHECK-LABEL: @lossy_ueq( 763; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 764; CHECK-NEXT: ret i1 [[R]] 765; 766 %e = fpext half %x to double 767 %r = fcmp ueq double %e, 65536.0 768 ret i1 %r 769} 770 771define i1 @lossy_une(half %x) { 772; CHECK-LABEL: @lossy_une( 773; CHECK-NEXT: ret i1 true 774; 775 %e = fpext half %x to float 776 %r = fcmp une float %e, 2049.0 777 ret i1 %r 778} 779 780define <2 x i1> @lossy_ogt(<2 x float> %x) { 781; CHECK-LABEL: @lossy_ogt( 782; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double> 783; CHECK-NEXT: [[R:%.*]] = fcmp ogt <2 x double> [[E]], splat (double 1.000000e-01) 784; CHECK-NEXT: ret <2 x i1> [[R]] 785; 786 %e = fpext <2 x float> %x to <2 x double> 787 %r = fcmp ogt <2 x double> %e, <double 0.1, double 0.1> 788 ret <2 x i1> %r 789} 790 791define i1 @lossy_oge(float %x, ptr %p) { 792; CHECK-LABEL: @lossy_oge( 793; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double 794; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8 795; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[E]], 1.000000e-01 796; CHECK-NEXT: ret i1 [[R]] 797; 798 %e = fpext float %x to double 799 store double %e, ptr %p 800 %r = fcmp oge double %e, 0.1 801 ret i1 %r 802} 803 804define i1 @lossy_olt(half %x) { 805; CHECK-LABEL: @lossy_olt( 806; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double 807; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[E]], 6.553600e+04 808; CHECK-NEXT: ret i1 [[R]] 809; 810 %e = fpext half %x to double 811 %r = fcmp olt double %e, 65536.0 812 ret i1 %r 813} 814 815define i1 @lossy_ole(half %x) { 816; CHECK-LABEL: @lossy_ole( 817; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float 818; CHECK-NEXT: [[R:%.*]] = fcmp ole float [[E]], 2.049000e+03 819; CHECK-NEXT: ret i1 [[R]] 820; 821 %e = fpext half %x to float 822 %r = fcmp ole float %e, 2049.0 823 ret i1 %r 824} 825 826define <2 x i1> @lossy_ugt(<2 x float> %x) { 827; CHECK-LABEL: @lossy_ugt( 828; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double> 829; CHECK-NEXT: [[R:%.*]] = fcmp ugt <2 x double> [[E]], splat (double 1.000000e-01) 830; CHECK-NEXT: ret <2 x i1> [[R]] 831; 832 %e = fpext <2 x float> %x to <2 x double> 833 %r = fcmp ugt <2 x double> %e, <double 0.1, double 0.1> 834 ret <2 x i1> %r 835} 836 837define i1 @lossy_uge(float %x, ptr %p) { 838; CHECK-LABEL: @lossy_uge( 839; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double 840; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8 841; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[E]], 1.000000e-01 842; CHECK-NEXT: ret i1 [[R]] 843; 844 %e = fpext float %x to double 845 store double %e, ptr %p 846 %r = fcmp uge double %e, 0.1 847 ret i1 %r 848} 849 850define i1 @lossy_ult(half %x) { 851; CHECK-LABEL: @lossy_ult( 852; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double 853; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[E]], 6.553600e+04 854; CHECK-NEXT: ret i1 [[R]] 855; 856 %e = fpext half %x to double 857 %r = fcmp ult double %e, 65536.0 858 ret i1 %r 859} 860 861define i1 @lossy_ule(half %x) { 862; CHECK-LABEL: @lossy_ule( 863; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float 864; CHECK-NEXT: [[R:%.*]] = fcmp ule float [[E]], 2.049000e+03 865; CHECK-NEXT: ret i1 [[R]] 866; 867 %e = fpext half %x to float 868 %r = fcmp ule float %e, 2049.0 869 ret i1 %r 870} 871 872define i1 @lossy_ord(half %x) { 873; CHECK-LABEL: @lossy_ord( 874; CHECK-NEXT: [[R:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 875; CHECK-NEXT: ret i1 [[R]] 876; 877 %e = fpext half %x to double 878 %r = fcmp ord double %e, 65536.0 879 ret i1 %r 880} 881 882define i1 @lossy_uno(half %x) { 883; CHECK-LABEL: @lossy_uno( 884; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 885; CHECK-NEXT: ret i1 [[R]] 886; 887 %e = fpext half %x to float 888 %r = fcmp uno float %e, 2049.0 889 ret i1 %r 890} 891 892define i1 @fneg_oeq(float %a) { 893; CHECK-LABEL: @fneg_oeq( 894; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00 895; CHECK-NEXT: ret i1 [[CMP]] 896; 897 %fneg = fneg float %a 898 %cmp = fcmp oeq float %fneg, %a 899 ret i1 %cmp 900} 901 902define i1 @fneg_ogt(half %a) { 903; CHECK-LABEL: @fneg_ogt( 904; CHECK-NEXT: [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000 905; CHECK-NEXT: ret i1 [[CMP]] 906; 907 %fneg = fneg half %a 908 %cmp = fcmp fast ogt half %fneg, %a 909 ret i1 %cmp 910} 911 912define <2 x i1> @fneg_oge(<2 x float> %a) { 913; CHECK-LABEL: @fneg_oge( 914; CHECK-NEXT: [[CMP:%.*]] = fcmp ole <2 x float> [[A:%.*]], zeroinitializer 915; CHECK-NEXT: ret <2 x i1> [[CMP]] 916; 917 %fneg = fneg fast <2 x float> %a 918 %cmp = fcmp oge <2 x float> %fneg, %a 919 ret <2 x i1> %cmp 920} 921 922define i1 @fneg_olt(float %a, ptr %q) { 923; CHECK-LABEL: @fneg_olt( 924; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]] 925; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4 926; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00 927; CHECK-NEXT: ret i1 [[CMP]] 928; 929 %fneg = fneg float %a 930 store float %fneg, ptr %q 931 %cmp = fcmp olt float %fneg, %a 932 ret i1 %cmp 933} 934 935define i1 @fneg_ole(float %a) { 936; CHECK-LABEL: @fneg_ole( 937; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00 938; CHECK-NEXT: ret i1 [[CMP]] 939; 940 %fneg = fneg float %a 941 %cmp = fcmp nsz ole float %fneg, %a 942 ret i1 %cmp 943} 944 945define i1 @fneg_one(float %a) { 946; CHECK-LABEL: @fneg_one( 947; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00 948; CHECK-NEXT: ret i1 [[CMP]] 949; 950 %fneg = fneg float %a 951 %cmp = fcmp nnan one float %fneg, %a 952 ret i1 %cmp 953} 954 955define i1 @fneg_ord(float %a) { 956; CHECK-LABEL: @fneg_ord( 957; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00 958; CHECK-NEXT: ret i1 [[CMP]] 959; 960 %fneg = fneg float %a 961 %cmp = fcmp ninf ord float %fneg, %a 962 ret i1 %cmp 963} 964 965define i1 @fneg_uno(float %a) { 966; CHECK-LABEL: @fneg_uno( 967; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00 968; CHECK-NEXT: ret i1 [[CMP]] 969; 970 %fneg = fneg float %a 971 %cmp = fcmp uno float %fneg, %a 972 ret i1 %cmp 973} 974 975define i1 @fneg_ueq(half %a) { 976; CHECK-LABEL: @fneg_ueq( 977; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000 978; CHECK-NEXT: ret i1 [[CMP]] 979; 980 %fneg = fneg half %a 981 %cmp = fcmp fast ueq half %fneg, %a 982 ret i1 %cmp 983} 984 985define <2 x i1> @fneg_ugt(<2 x float> %a) { 986; CHECK-LABEL: @fneg_ugt( 987; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x float> [[A:%.*]], zeroinitializer 988; CHECK-NEXT: ret <2 x i1> [[CMP]] 989; 990 %fneg = fneg fast <2 x float> %a 991 %cmp = fcmp ugt <2 x float> %fneg, %a 992 ret <2 x i1> %cmp 993} 994 995define i1 @fneg_uge(float %a, ptr %q) { 996; CHECK-LABEL: @fneg_uge( 997; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]] 998; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4 999; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+00 1000; CHECK-NEXT: ret i1 [[CMP]] 1001; 1002 %fneg = fneg float %a 1003 store float %fneg, ptr %q 1004 %cmp = fcmp uge float %fneg, %a 1005 ret i1 %cmp 1006} 1007 1008define i1 @fneg_ult(float %a) { 1009; CHECK-LABEL: @fneg_ult( 1010; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+00 1011; CHECK-NEXT: ret i1 [[CMP]] 1012; 1013 %fneg = fneg float %a 1014 %cmp = fcmp nsz ult float %fneg, %a 1015 ret i1 %cmp 1016} 1017 1018define i1 @fneg_ule(float %a) { 1019; CHECK-LABEL: @fneg_ule( 1020; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+00 1021; CHECK-NEXT: ret i1 [[CMP]] 1022; 1023 %fneg = fneg float %a 1024 %cmp = fcmp nnan ule float %fneg, %a 1025 ret i1 %cmp 1026} 1027 1028define i1 @fneg_une(float %a) { 1029; CHECK-LABEL: @fneg_une( 1030; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+00 1031; CHECK-NEXT: ret i1 [[CMP]] 1032; 1033 %fneg = fneg float %a 1034 %cmp = fcmp ninf une float %fneg, %a 1035 ret i1 %cmp 1036} 1037 1038define i1 @fneg_oeq_swap(float %p) { 1039; CHECK-LABEL: @fneg_oeq_swap( 1040; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1041; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00 1042; CHECK-NEXT: ret i1 [[CMP]] 1043; 1044 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1045 %fneg = fneg float %a 1046 %cmp = fcmp oeq float %a, %fneg 1047 ret i1 %cmp 1048} 1049 1050define i1 @fneg_ogt_swap(half %p) { 1051; CHECK-LABEL: @fneg_ogt_swap( 1052; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]] 1053; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ogt half [[A]], 0xH0000 1054; CHECK-NEXT: ret i1 [[CMP]] 1055; 1056 %a = fadd half %p, %p ; thwart complexity-based canonicalization 1057 %fneg = fneg half %a 1058 %cmp = fcmp fast ogt half %a, %fneg 1059 ret i1 %cmp 1060} 1061 1062define <2 x i1> @fneg_oge_swap(<2 x float> %p) { 1063; CHECK-LABEL: @fneg_oge_swap( 1064; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]] 1065; CHECK-NEXT: [[CMP:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer 1066; CHECK-NEXT: ret <2 x i1> [[CMP]] 1067; 1068 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization 1069 %fneg = fneg fast <2 x float> %a 1070 %cmp = fcmp oge <2 x float> %a, %fneg 1071 ret <2 x i1> %cmp 1072} 1073 1074define i1 @fneg_olt_swap(float %p, ptr %q) { 1075; CHECK-LABEL: @fneg_olt_swap( 1076; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1077; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]] 1078; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4 1079; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+00 1080; CHECK-NEXT: ret i1 [[CMP]] 1081; 1082 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1083 %fneg = fneg float %a 1084 store float %fneg, ptr %q 1085 %cmp = fcmp olt float %a, %fneg 1086 ret i1 %cmp 1087} 1088 1089define i1 @fneg_ole_swap(float %p) { 1090; CHECK-LABEL: @fneg_ole_swap( 1091; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1092; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ole float [[A]], 0.000000e+00 1093; CHECK-NEXT: ret i1 [[CMP]] 1094; 1095 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1096 %fneg = fneg float %a 1097 %cmp = fcmp nsz ole float %a, %fneg 1098 ret i1 %cmp 1099} 1100 1101define i1 @fneg_one_swap(float %p) { 1102; CHECK-LABEL: @fneg_one_swap( 1103; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1104; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A]], 0.000000e+00 1105; CHECK-NEXT: ret i1 [[CMP]] 1106; 1107 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1108 %fneg = fneg float %a 1109 %cmp = fcmp nnan one float %a, %fneg 1110 ret i1 %cmp 1111} 1112 1113define i1 @fneg_ord_swap(float %p) { 1114; CHECK-LABEL: @fneg_ord_swap( 1115; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1116; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A]], 0.000000e+00 1117; CHECK-NEXT: ret i1 [[CMP]] 1118; 1119 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1120 %fneg = fneg float %a 1121 %cmp = fcmp ninf ord float %a, %fneg 1122 ret i1 %cmp 1123} 1124 1125define i1 @fneg_uno_swap(float %p) { 1126; CHECK-LABEL: @fneg_uno_swap( 1127; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1128; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A]], 0.000000e+00 1129; CHECK-NEXT: ret i1 [[CMP]] 1130; 1131 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1132 %fneg = fneg float %a 1133 %cmp = fcmp uno float %a, %fneg 1134 ret i1 %cmp 1135} 1136 1137define i1 @fneg_ueq_swap(half %p) { 1138; CHECK-LABEL: @fneg_ueq_swap( 1139; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]] 1140; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A]], 0xH0000 1141; CHECK-NEXT: ret i1 [[CMP]] 1142; 1143 %a = fadd half %p, %p ; thwart complexity-based canonicalization 1144 %fneg = fneg half %a 1145 %cmp = fcmp fast ueq half %a, %fneg 1146 ret i1 %cmp 1147} 1148 1149define <2 x i1> @fneg_ugt_swap(<2 x float> %p) { 1150; CHECK-LABEL: @fneg_ugt_swap( 1151; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]] 1152; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], zeroinitializer 1153; CHECK-NEXT: ret <2 x i1> [[CMP]] 1154; 1155 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization 1156 %fneg = fneg fast <2 x float> %a 1157 %cmp = fcmp ugt <2 x float> %a, %fneg 1158 ret <2 x i1> %cmp 1159} 1160 1161define i1 @fneg_uge_swap(float %p, ptr %q) { 1162; CHECK-LABEL: @fneg_uge_swap( 1163; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1164; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]] 1165; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4 1166; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+00 1167; CHECK-NEXT: ret i1 [[CMP]] 1168; 1169 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1170 %fneg = fneg float %a 1171 store float %fneg, ptr %q 1172 %cmp = fcmp uge float %a, %fneg 1173 ret i1 %cmp 1174} 1175 1176define i1 @fneg_ult_swap(float %p) { 1177; CHECK-LABEL: @fneg_ult_swap( 1178; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1179; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ult float [[A]], 0.000000e+00 1180; CHECK-NEXT: ret i1 [[CMP]] 1181; 1182 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1183 %fneg = fneg float %a 1184 %cmp = fcmp nsz ult float %a, %fneg 1185 ret i1 %cmp 1186} 1187 1188define i1 @fneg_ule_swap(float %p) { 1189; CHECK-LABEL: @fneg_ule_swap( 1190; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1191; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ule float [[A]], 0.000000e+00 1192; CHECK-NEXT: ret i1 [[CMP]] 1193; 1194 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1195 %fneg = fneg float %a 1196 %cmp = fcmp nnan ule float %a, %fneg 1197 ret i1 %cmp 1198} 1199 1200define i1 @fneg_une_swap(float %p) { 1201; CHECK-LABEL: @fneg_une_swap( 1202; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]] 1203; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A]], 0.000000e+00 1204; CHECK-NEXT: ret i1 [[CMP]] 1205; 1206 %a = fadd float %p, %p ; thwart complexity-based canonicalization 1207 %fneg = fneg float %a 1208 %cmp = fcmp ninf une float %a, %fneg 1209 ret i1 %cmp 1210} 1211 1212define i1 @bitcast_eq0(i32 %x) { 1213; CHECK-LABEL: @bitcast_eq0( 1214; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 2147483647 1215; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 0 1216; CHECK-NEXT: ret i1 [[R]] 1217; 1218 %f = bitcast i32 %x to float 1219 %r = fcmp oeq float %f, 0.0 1220 ret i1 %r 1221} 1222 1223define <2 x i1> @bitcast_ne0(<2 x i32> %x) { 1224; CHECK-LABEL: @bitcast_ne0( 1225; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 2147483647) 1226; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 1227; CHECK-NEXT: ret <2 x i1> [[R]] 1228; 1229 %f = bitcast <2 x i32> %x to <2 x float> 1230 %r = fcmp une <2 x float> %f, <float 0.0, float 0.0> 1231 ret <2 x i1> %r 1232} 1233 1234; negative test - extra use 1235 1236define i1 @bitcast_eq0_use(i32 %x) { 1237; CHECK-LABEL: @bitcast_eq0_use( 1238; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to float 1239; CHECK-NEXT: call void @use(float [[F]]) 1240; CHECK-NEXT: [[R:%.*]] = fcmp oeq float [[F]], 0.000000e+00 1241; CHECK-NEXT: ret i1 [[R]] 1242; 1243 %f = bitcast i32 %x to float 1244 call void @use(float %f) 1245 %r = fcmp oeq float %f, 0.0 1246 ret i1 %r 1247} 1248 1249; negative test - this could be transformed, but requires a new bitcast 1250 1251define i1 @bitcast_nonint_eq0(<2 x i16> %x) { 1252; CHECK-LABEL: @bitcast_nonint_eq0( 1253; CHECK-NEXT: [[F:%.*]] = bitcast <2 x i16> [[X:%.*]] to float 1254; CHECK-NEXT: [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00 1255; CHECK-NEXT: ret i1 [[R]] 1256; 1257 %f = bitcast <2 x i16> %x to float 1258 %r = fcmp ogt float %f, 0.0 1259 ret i1 %r 1260} 1261 1262; negative test - wrong predicate 1263 1264define i1 @bitcast_gt0(i32 %x) { 1265; CHECK-LABEL: @bitcast_gt0( 1266; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to float 1267; CHECK-NEXT: [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00 1268; CHECK-NEXT: ret i1 [[R]] 1269; 1270 %f = bitcast i32 %x to float 1271 %r = fcmp ogt float %f, 0.0 1272 ret i1 %r 1273} 1274 1275; negative test - this could be transformed, but requires a new bitcast 1276 1277define <1 x i1> @bitcast_1vec_eq0(i32 %x) { 1278; CHECK-LABEL: @bitcast_1vec_eq0( 1279; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to <1 x float> 1280; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <1 x float> [[F]], zeroinitializer 1281; CHECK-NEXT: ret <1 x i1> [[CMP]] 1282; 1283 %f = bitcast i32 %x to <1 x float> 1284 %cmp = fcmp oeq <1 x float> %f, zeroinitializer 1285 ret <1 x i1> %cmp 1286} 1287 1288; Simplify fcmp (x + 0.0), y => fcmp x, y 1289 1290define i1 @fcmp_fadd_zero_ugt(float %x, float %y) { 1291; CHECK-LABEL: @fcmp_fadd_zero_ugt( 1292; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]] 1293; CHECK-NEXT: ret i1 [[CMP]] 1294; 1295 %add = fadd float %x, 0.000000e+00 1296 %cmp = fcmp ugt float %add, %y 1297 ret i1 %cmp 1298} 1299 1300define i1 @fcmp_fadd_zero_uge(float %x, float %y) { 1301; CHECK-LABEL: @fcmp_fadd_zero_uge( 1302; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]] 1303; CHECK-NEXT: ret i1 [[CMP]] 1304; 1305 %add = fadd float %x, 0.000000e+00 1306 %cmp = fcmp uge float %add, %y 1307 ret i1 %cmp 1308} 1309 1310define i1 @fcmp_fadd_zero_ogt(float %x, float %y) { 1311; CHECK-LABEL: @fcmp_fadd_zero_ogt( 1312; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]] 1313; CHECK-NEXT: ret i1 [[CMP]] 1314; 1315 %add = fadd float %x, 0.000000e+00 1316 %cmp = fcmp ogt float %add, %y 1317 ret i1 %cmp 1318} 1319 1320define i1 @fcmp_fadd_zero_oge(float %x, float %y) { 1321; CHECK-LABEL: @fcmp_fadd_zero_oge( 1322; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], [[Y:%.*]] 1323; CHECK-NEXT: ret i1 [[CMP]] 1324; 1325 %add = fadd float %x, 0.000000e+00 1326 %cmp = fcmp oge float %add, %y 1327 ret i1 %cmp 1328} 1329 1330define i1 @fcmp_fadd_zero_ult(float %x, float %y) { 1331; CHECK-LABEL: @fcmp_fadd_zero_ult( 1332; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]] 1333; CHECK-NEXT: ret i1 [[CMP]] 1334; 1335 %add = fadd float %x, 0.000000e+00 1336 %cmp = fcmp ult float %add, %y 1337 ret i1 %cmp 1338} 1339 1340define i1 @fcmp_fadd_zero_ule(float %x, float %y) { 1341; CHECK-LABEL: @fcmp_fadd_zero_ule( 1342; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]] 1343; CHECK-NEXT: ret i1 [[CMP]] 1344; 1345 %add = fadd float %x, 0.000000e+00 1346 %cmp = fcmp ule float %add, %y 1347 ret i1 %cmp 1348} 1349 1350define i1 @fcmp_fadd_zero_olt(float %x, float %y) { 1351; CHECK-LABEL: @fcmp_fadd_zero_olt( 1352; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]] 1353; CHECK-NEXT: ret i1 [[CMP]] 1354; 1355 %add = fadd float %x, 0.000000e+00 1356 %cmp = fcmp olt float %add, %y 1357 ret i1 %cmp 1358} 1359 1360define i1 @fcmp_fadd_zero_ole(float %x, float %y) { 1361; CHECK-LABEL: @fcmp_fadd_zero_ole( 1362; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]] 1363; CHECK-NEXT: ret i1 [[CMP]] 1364; 1365 %add = fadd float %x, 0.000000e+00 1366 %cmp = fcmp ole float %add, %y 1367 ret i1 %cmp 1368} 1369 1370define i1 @fcmp_fadd_zero_oeq(float %x, float %y) { 1371; CHECK-LABEL: @fcmp_fadd_zero_oeq( 1372; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]] 1373; CHECK-NEXT: ret i1 [[CMP]] 1374; 1375 %add = fadd float %x, 0.000000e+00 1376 %cmp = fcmp oeq float %add, %y 1377 ret i1 %cmp 1378} 1379 1380define i1 @fcmp_fadd_zero_one(float %x, float %y) { 1381; CHECK-LABEL: @fcmp_fadd_zero_one( 1382; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[X:%.*]], [[Y:%.*]] 1383; CHECK-NEXT: ret i1 [[CMP]] 1384; 1385 %add = fadd float %x, 0.000000e+00 1386 %cmp = fcmp one float %add, %y 1387 ret i1 %cmp 1388} 1389 1390define i1 @fcmp_fadd_zero_ueq(float %x, float %y) { 1391; CHECK-LABEL: @fcmp_fadd_zero_ueq( 1392; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]] 1393; CHECK-NEXT: ret i1 [[CMP]] 1394; 1395 %add = fadd float %x, 0.000000e+00 1396 %cmp = fcmp ueq float %add, %y 1397 ret i1 %cmp 1398} 1399 1400define i1 @fcmp_fadd_zero_une(float %x, float %y) { 1401; CHECK-LABEL: @fcmp_fadd_zero_une( 1402; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]] 1403; CHECK-NEXT: ret i1 [[CMP]] 1404; 1405 %add = fadd float %x, 0.000000e+00 1406 %cmp = fcmp une float %add, %y 1407 ret i1 %cmp 1408} 1409 1410define i1 @fcmp_fadd_zero_ord(float %x, float %y) { 1411; CHECK-LABEL: @fcmp_fadd_zero_ord( 1412; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]] 1413; CHECK-NEXT: ret i1 [[CMP]] 1414; 1415 %add = fadd float %x, 0.000000e+00 1416 %cmp = fcmp ord float %add, %y 1417 ret i1 %cmp 1418} 1419 1420define i1 @fcmp_fadd_zero_uno(float %x, float %y) { 1421; CHECK-LABEL: @fcmp_fadd_zero_uno( 1422; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]] 1423; CHECK-NEXT: ret i1 [[CMP]] 1424; 1425 %add = fadd float %x, 0.000000e+00 1426 %cmp = fcmp uno float %add, %y 1427 ret i1 %cmp 1428} 1429 1430define i1 @fcmp_fadd_neg_zero(float %x, float %y) { 1431; CHECK-LABEL: @fcmp_fadd_neg_zero( 1432; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]] 1433; CHECK-NEXT: ret i1 [[CMP]] 1434; 1435 %add = fadd float %x, -0.000000e+00 1436 %cmp = fcmp ugt float %add, %y 1437 ret i1 %cmp 1438} 1439 1440define i1 @fcmp_fadd_zero_switched(float %x, float %y) { 1441; CHECK-LABEL: @fcmp_fadd_zero_switched( 1442; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]] 1443; CHECK-NEXT: ret i1 [[CMP]] 1444; 1445 %add = fadd float %y, 0.000000e+00 1446 %cmp = fcmp ugt float %x, %add 1447 ret i1 %cmp 1448} 1449 1450define <2 x i1> @fcmp_fadd_zero_vec(<2 x float> %x, <2 x float> %y) { 1451; CHECK-LABEL: @fcmp_fadd_zero_vec( 1452; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt <2 x float> [[X:%.*]], [[Y:%.*]] 1453; CHECK-NEXT: ret <2 x i1> [[CMP]] 1454; 1455 %add = fadd <2 x float> %x, <float 0.0, float -0.0> 1456 %cmp = fcmp ugt <2 x float> %add, %y 1457 ret <2 x i1> %cmp 1458} 1459 1460define i1 @fcmp_fast_fadd_fast_zero(float %x, float %y) { 1461; CHECK-LABEL: @fcmp_fast_fadd_fast_zero( 1462; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]] 1463; CHECK-NEXT: ret i1 [[CMP]] 1464; 1465 %add = fadd fast float %x, 0.000000e+00 1466 %cmp = fcmp fast ugt float %add, %y 1467 ret i1 %cmp 1468} 1469 1470define i1 @fcmp_fast_fadd_zero(float %x, float %y) { 1471; CHECK-LABEL: @fcmp_fast_fadd_zero( 1472; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]] 1473; CHECK-NEXT: ret i1 [[CMP]] 1474; 1475 %add = fadd float %x, 0.000000e+00 1476 %cmp = fcmp fast ugt float %add, %y 1477 ret i1 %cmp 1478} 1479 1480define i1 @fcmp_fadd_fast_zero(float %x, float %y) { 1481; CHECK-LABEL: @fcmp_fadd_fast_zero( 1482; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]] 1483; CHECK-NEXT: ret i1 [[CMP]] 1484; 1485 %add = fadd fast float %x, 0.000000e+00 1486 %cmp = fcmp ugt float %add, %y 1487 ret i1 %cmp 1488} 1489 1490define i1 @fcmp_ueq_sel_x_negx(float %x) { 1491; CHECK-LABEL: @fcmp_ueq_sel_x_negx( 1492; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00 1493; CHECK-NEXT: ret i1 [[RES]] 1494; 1495 %f = fcmp ueq float %x, 0.000000e+00 1496 %neg = fneg float %x 1497 %sel = select i1 %f, float %x, float %neg 1498 %res = fcmp ueq float %sel, 0.000000e+00 1499 ret i1 %res 1500} 1501 1502define i1 @fcmp_une_sel_x_negx(float %x) { 1503; CHECK-LABEL: @fcmp_une_sel_x_negx( 1504; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 1505; CHECK-NEXT: ret i1 [[RES]] 1506; 1507 %f = fcmp une float %x, 0.000000e+00 1508 %neg = fneg float %x 1509 %sel = select i1 %f, float %x, float %neg 1510 %res = fcmp une float %sel, 0.000000e+00 1511 ret i1 %res 1512} 1513 1514define i1 @fcmp_oeq_sel_x_negx(float %x) { 1515; CHECK-LABEL: @fcmp_oeq_sel_x_negx( 1516; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 1517; CHECK-NEXT: ret i1 [[RES]] 1518; 1519 %f = fcmp oeq float %x, 0.000000e+00 1520 %neg = fneg float %x 1521 %sel = select i1 %f, float %x, float %neg 1522 %res = fcmp oeq float %sel, 0.000000e+00 1523 ret i1 %res 1524} 1525 1526define i1 @fcmp_one_sel_x_negx(float %x) { 1527; CHECK-LABEL: @fcmp_one_sel_x_negx( 1528; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 1529; CHECK-NEXT: ret i1 [[RES]] 1530; 1531 %f = fcmp one float %x, 0.000000e+00 1532 %neg = fneg float %x 1533 %sel = select i1 %f, float %x, float %neg 1534 %res = fcmp one float %sel, 0.000000e+00 1535 ret i1 %res 1536} 1537 1538define i1 @fcmp_ueq_sel_x_negx_nzero(float %x) { 1539; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero( 1540; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00 1541; CHECK-NEXT: ret i1 [[RES]] 1542; 1543 %f = fcmp ueq float %x, 0.000000e+00 1544 %neg = fneg float %x 1545 %sel = select i1 %f, float %x, float %neg 1546 %res = fcmp ueq float %sel, -0.000000e+00 1547 ret i1 %res 1548} 1549 1550define i1 @fcmp_une_sel_x_negx_nzero(float %x) { 1551; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero( 1552; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 1553; CHECK-NEXT: ret i1 [[RES]] 1554; 1555 %f = fcmp une float %x, 0.000000e+00 1556 %neg = fneg float %x 1557 %sel = select i1 %f, float %x, float %neg 1558 %res = fcmp une float %sel, -0.000000e+00 1559 ret i1 %res 1560} 1561 1562define i1 @fcmp_oeq_sel_x_negx_nzero(float %x) { 1563; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero( 1564; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 1565; CHECK-NEXT: ret i1 [[RES]] 1566; 1567 %f = fcmp oeq float %x, 0.000000e+00 1568 %neg = fneg float %x 1569 %sel = select i1 %f, float %x, float %neg 1570 %res = fcmp oeq float %sel, -0.000000e+00 1571 ret i1 %res 1572} 1573 1574define i1 @fcmp_one_sel_x_negx_nzero(float %x) { 1575; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero( 1576; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 1577; CHECK-NEXT: ret i1 [[RES]] 1578; 1579 %f = fcmp one float %x, 0.000000e+00 1580 %neg = fneg float %x 1581 %sel = select i1 %f, float %x, float %neg 1582 %res = fcmp one float %sel, -0.000000e+00 1583 ret i1 %res 1584} 1585 1586define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) { 1587; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec( 1588; CHECK-NEXT: [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer 1589; CHECK-NEXT: ret <8 x i1> [[RES]] 1590; 1591 %f = fcmp ueq <8 x float> %x, zeroinitializer 1592 %neg = fneg <8 x float> %x 1593 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg 1594 %res = fcmp ueq <8 x float> %sel, zeroinitializer 1595 ret <8 x i1> %res 1596} 1597 1598define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) { 1599; CHECK-LABEL: @fcmp_une_sel_x_negx_vec( 1600; CHECK-NEXT: [[RES:%.*]] = fcmp une <8 x float> [[X:%.*]], zeroinitializer 1601; CHECK-NEXT: ret <8 x i1> [[RES]] 1602; 1603 %f = fcmp une <8 x float> %x, zeroinitializer 1604 %neg = fneg <8 x float> %x 1605 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg 1606 %res = fcmp une <8 x float> %sel, zeroinitializer 1607 ret <8 x i1> %res 1608} 1609 1610define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) { 1611; CHECK-LABEL: @fcmp_oeq_sel_x_negx_vec( 1612; CHECK-NEXT: [[RES:%.*]] = fcmp oeq <8 x float> [[X:%.*]], zeroinitializer 1613; CHECK-NEXT: ret <8 x i1> [[RES]] 1614; 1615 %f = fcmp oeq <8 x float> %x, zeroinitializer 1616 %neg = fneg <8 x float> %x 1617 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg 1618 %res = fcmp oeq <8 x float> %sel, zeroinitializer 1619 ret <8 x i1> %res 1620} 1621 1622define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) { 1623; CHECK-LABEL: @fcmp_one_sel_x_negx_vec( 1624; CHECK-NEXT: [[RES:%.*]] = fcmp one <8 x float> [[X:%.*]], zeroinitializer 1625; CHECK-NEXT: ret <8 x i1> [[RES]] 1626; 1627 %f = fcmp one <8 x float> %x, zeroinitializer 1628 %neg = fneg <8 x float> %x 1629 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg 1630 %res = fcmp one <8 x float> %sel, zeroinitializer 1631 ret <8 x i1> %res 1632} 1633 1634define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) { 1635; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec( 1636; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf oeq <2 x float> [[X:%.*]], zeroinitializer 1637; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1638; 1639 %fneg = fneg <2 x float> %x 1640 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1641 %icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0> 1642 ret <2 x i1> %icmp 1643} 1644 1645define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) { 1646; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec( 1647; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf one <2 x float> [[X:%.*]], zeroinitializer 1648; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1649; 1650 %fneg = fneg <2 x float> %x 1651 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1652 %icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0> 1653 ret <2 x i1> %icmp 1654} 1655 1656define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) { 1657; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec( 1658; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf ueq <2 x float> [[X:%.*]], zeroinitializer 1659; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1660; 1661 %fneg = fneg <2 x float> %x 1662 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1663 %icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0> 1664 ret <2 x i1> %icmp 1665} 1666 1667define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) { 1668; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec( 1669; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf une <2 x float> [[X:%.*]], zeroinitializer 1670; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1671; 1672 %fneg = fneg <2 x float> %x 1673 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1674 %icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0> 1675 ret <2 x i1> %icmp 1676} 1677 1678define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) { 1679; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec( 1680; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan oeq <2 x float> [[X:%.*]], zeroinitializer 1681; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1682; 1683 %fneg = fneg <2 x float> %x 1684 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1685 %icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0> 1686 ret <2 x i1> %icmp 1687} 1688 1689define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) { 1690; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec( 1691; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan one <2 x float> [[X:%.*]], zeroinitializer 1692; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1693; 1694 %fneg = fneg <2 x float> %x 1695 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1696 %icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0> 1697 ret <2 x i1> %icmp 1698} 1699 1700define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) { 1701; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec( 1702; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan ueq <2 x float> [[X:%.*]], zeroinitializer 1703; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1704; 1705 %fneg = fneg <2 x float> %x 1706 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1707 %icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0> 1708 ret <2 x i1> %icmp 1709} 1710 1711define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) { 1712; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec( 1713; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan une <2 x float> [[X:%.*]], zeroinitializer 1714; CHECK-NEXT: ret <2 x i1> [[ICMP]] 1715; 1716 %fneg = fneg <2 x float> %x 1717 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg 1718 %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0> 1719 ret <2 x i1> %icmp 1720} 1721 1722; negative test - extra use 1723 1724define i1 @fcmp_ueq_fsub_nnan_const_extra_use(float %x, float %y) { 1725; CHECK-LABEL: @fcmp_ueq_fsub_nnan_const_extra_use( 1726; CHECK-NEXT: [[FS:%.*]] = fsub nnan float [[X:%.*]], [[Y:%.*]] 1727; CHECK-NEXT: call void @use(float [[FS]]) 1728; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq float [[FS]], 0.000000e+00 1729; CHECK-NEXT: ret i1 [[CMP]] 1730; 1731 %fs = fsub nnan float %x, %y 1732 call void @use(float %fs) 1733 %cmp = fcmp nnan ueq float %fs, 0.000000e+00 1734 ret i1 %cmp 1735} 1736 1737; negative test - extra use 1738 1739define i1 @fcmp_oeq_fsub_ninf_const_extra_use(float %x, float %y) { 1740; CHECK-LABEL: @fcmp_oeq_fsub_ninf_const_extra_use( 1741; CHECK-NEXT: [[FS:%.*]] = fsub ninf float [[X:%.*]], [[Y:%.*]] 1742; CHECK-NEXT: call void @use(float [[FS]]) 1743; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq float [[FS]], 0.000000e+00 1744; CHECK-NEXT: ret i1 [[CMP]] 1745; 1746 %fs = fsub ninf float %x, %y 1747 call void @use(float %fs) 1748 %cmp = fcmp ninf oeq float %fs, 0.000000e+00 1749 ret i1 %cmp 1750} 1751 1752define i1 @fcmp_oeq_fsub_const(float %x, float %y) { 1753; CHECK-LABEL: @fcmp_oeq_fsub_const( 1754; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1755; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[FS]], 0.000000e+00 1756; CHECK-NEXT: ret i1 [[CMP]] 1757; 1758 %fs = fsub float %x, %y 1759 %cmp = fcmp oeq float %fs, 0.000000e+00 1760 ret i1 %cmp 1761} 1762 1763define i1 @fcmp_oge_fsub_const(float %x, float %y) { 1764; CHECK-LABEL: @fcmp_oge_fsub_const( 1765; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1766; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[FS]], 0.000000e+00 1767; CHECK-NEXT: ret i1 [[CMP]] 1768; 1769 %fs = fsub float %x, %y 1770 %cmp = fcmp oge float %fs, 0.000000e+00 1771 ret i1 %cmp 1772} 1773 1774define i1 @fcmp_ole_fsub_const(float %x, float %y) { 1775; CHECK-LABEL: @fcmp_ole_fsub_const( 1776; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1777; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[FS]], 0.000000e+00 1778; CHECK-NEXT: ret i1 [[CMP]] 1779; 1780 %fs = fsub float %x, %y 1781 %cmp = fcmp ole float %fs, 0.000000e+00 1782 ret i1 %cmp 1783} 1784 1785define i1 @fcmp_ueq_fsub_const(float %x, float %y) { 1786; CHECK-LABEL: @fcmp_ueq_fsub_const( 1787; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]] 1788; CHECK-NEXT: ret i1 [[CMP]] 1789; 1790 %fs = fsub float %x, %y 1791 %cmp = fcmp ueq float %fs, 0.000000e+00 1792 ret i1 %cmp 1793} 1794 1795define i1 @fcmp_uge_fsub_const(float %x, float %y) { 1796; CHECK-LABEL: @fcmp_uge_fsub_const( 1797; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]] 1798; CHECK-NEXT: ret i1 [[CMP]] 1799; 1800 %fs = fsub float %x, %y 1801 %cmp = fcmp uge float %fs, 0.000000e+00 1802 ret i1 %cmp 1803} 1804 1805define i1 @fcmp_ule_fsub_const(float %x, float %y) { 1806; CHECK-LABEL: @fcmp_ule_fsub_const( 1807; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]] 1808; CHECK-NEXT: ret i1 [[CMP]] 1809; 1810 %fs = fsub float %x, %y 1811 %cmp = fcmp ule float %fs, 0.000000e+00 1812 ret i1 %cmp 1813} 1814 1815define i1 @fcmp_ugt_fsub_const(float %x, float %y) { 1816; CHECK-LABEL: @fcmp_ugt_fsub_const( 1817; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1818; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[FS]], 0.000000e+00 1819; CHECK-NEXT: ret i1 [[CMP]] 1820; 1821 %fs = fsub float %x, %y 1822 %cmp = fcmp ugt float %fs, 0.000000e+00 1823 ret i1 %cmp 1824} 1825 1826define i1 @fcmp_ult_fsub_const(float %x, float %y) { 1827; CHECK-LABEL: @fcmp_ult_fsub_const( 1828; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1829; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[FS]], 0.000000e+00 1830; CHECK-NEXT: ret i1 [[CMP]] 1831; 1832 %fs = fsub float %x, %y 1833 %cmp = fcmp ult float %fs, 0.000000e+00 1834 ret i1 %cmp 1835} 1836 1837define i1 @fcmp_une_fsub_const(float %x, float %y) { 1838; CHECK-LABEL: @fcmp_une_fsub_const( 1839; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] 1840; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[FS]], 0.000000e+00 1841; CHECK-NEXT: ret i1 [[CMP]] 1842; 1843 %fs = fsub float %x, %y 1844 %cmp = fcmp une float %fs, 0.000000e+00 1845 ret i1 %cmp 1846} 1847 1848define <8 x i1> @fcmp_uge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1849; CHECK-LABEL: @fcmp_uge_fsub_const_ninf_vec( 1850; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf uge <8 x float> [[X:%.*]], [[Y:%.*]] 1851; CHECK-NEXT: ret <8 x i1> [[CMP]] 1852; 1853 %fs = fsub ninf <8 x float> %x, %y 1854 %cmp = fcmp ninf uge <8 x float> %fs, zeroinitializer 1855 ret <8 x i1> %cmp 1856} 1857 1858define <8 x i1> @fcmp_ule_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1859; CHECK-LABEL: @fcmp_ule_fsub_const_ninf_vec( 1860; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ule <8 x float> [[X:%.*]], [[Y:%.*]] 1861; CHECK-NEXT: ret <8 x i1> [[CMP]] 1862; 1863 %fs = fsub ninf <8 x float> %x, %y 1864 %cmp = fcmp ninf ule <8 x float> %fs, zeroinitializer 1865 ret <8 x i1> %cmp 1866} 1867 1868define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1869; CHECK-LABEL: @fcmp_ueq_fsub_const_ninf_vec( 1870; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ueq <8 x float> [[X:%.*]], [[Y:%.*]] 1871; CHECK-NEXT: ret <8 x i1> [[CMP]] 1872; 1873 %fs = fsub ninf <8 x float> %x, %y 1874 %cmp = fcmp ninf ueq <8 x float> %fs, zeroinitializer 1875 ret <8 x i1> %cmp 1876} 1877 1878define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1879; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec( 1880; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oge <8 x float> [[X:%.*]], [[Y:%.*]] 1881; CHECK-NEXT: ret <8 x i1> [[CMP]] 1882; 1883 %fs = fsub ninf <8 x float> %x, %y 1884 %cmp = fcmp ninf oge <8 x float> %fs, zeroinitializer 1885 ret <8 x i1> %cmp 1886} 1887 1888define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1889; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec( 1890; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ole <8 x float> [[X:%.*]], [[Y:%.*]] 1891; CHECK-NEXT: ret <8 x i1> [[CMP]] 1892; 1893 %fs = fsub ninf <8 x float> %x, %y 1894 %cmp = fcmp ninf ole <8 x float> %fs, zeroinitializer 1895 ret <8 x i1> %cmp 1896} 1897 1898define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1899; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec( 1900; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[X:%.*]], [[Y:%.*]] 1901; CHECK-NEXT: ret <8 x i1> [[CMP]] 1902; 1903 %fs = fsub ninf <8 x float> %x, %y 1904 %cmp = fcmp ninf oeq <8 x float> %fs, zeroinitializer 1905 ret <8 x i1> %cmp 1906} 1907 1908define <8 x i1> @fcmp_ogt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1909; CHECK-LABEL: @fcmp_ogt_fsub_const_ninf_vec( 1910; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <8 x float> [[X:%.*]], [[Y:%.*]] 1911; CHECK-NEXT: ret <8 x i1> [[CMP]] 1912; 1913 %fs = fsub ninf <8 x float> %x, %y 1914 %cmp = fcmp ninf ogt <8 x float> %fs, zeroinitializer 1915 ret <8 x i1> %cmp 1916} 1917 1918define <8 x i1> @fcmp_olt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1919; CHECK-LABEL: @fcmp_olt_fsub_const_ninf_vec( 1920; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <8 x float> [[X:%.*]], [[Y:%.*]] 1921; CHECK-NEXT: ret <8 x i1> [[CMP]] 1922; 1923 %fs = fsub ninf <8 x float> %x, %y 1924 %cmp = fcmp ninf olt <8 x float> %fs, zeroinitializer 1925 ret <8 x i1> %cmp 1926} 1927 1928define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1929; CHECK-LABEL: @fcmp_one_fsub_const_ninf_vec( 1930; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf one <8 x float> [[X:%.*]], [[Y:%.*]] 1931; CHECK-NEXT: ret <8 x i1> [[CMP]] 1932; 1933 %fs = fsub ninf <8 x float> %x, %y 1934 %cmp = fcmp ninf one <8 x float> %fs, zeroinitializer 1935 ret <8 x i1> %cmp 1936} 1937 1938define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1939; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec( 1940; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[X:%.*]], [[Y:%.*]] 1941; CHECK-NEXT: ret <8 x i1> [[CMP]] 1942; 1943 %fs = fsub ninf <8 x float> %x, %y 1944 %cmp = fcmp ninf ugt <8 x float> %fs, zeroinitializer 1945 ret <8 x i1> %cmp 1946} 1947 1948define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1949; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec( 1950; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ult <8 x float> [[X:%.*]], [[Y:%.*]] 1951; CHECK-NEXT: ret <8 x i1> [[CMP]] 1952; 1953 %fs = fsub ninf <8 x float> %x, %y 1954 %cmp = fcmp ninf ult <8 x float> %fs, zeroinitializer 1955 ret <8 x i1> %cmp 1956} 1957 1958define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) { 1959; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec( 1960; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une <8 x float> [[X:%.*]], [[Y:%.*]] 1961; CHECK-NEXT: ret <8 x i1> [[CMP]] 1962; 1963 %fs = fsub ninf <8 x float> %x, %y 1964 %cmp = fcmp ninf une <8 x float> %fs, zeroinitializer 1965 ret <8 x i1> %cmp 1966} 1967 1968define <8 x i1> @fcmp_uge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 1969; CHECK-LABEL: @fcmp_uge_fsub_const_nnan_vec( 1970; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan uge <8 x float> [[X:%.*]], [[Y:%.*]] 1971; CHECK-NEXT: ret <8 x i1> [[CMP]] 1972; 1973 %fs = fsub nnan <8 x float> %x, %y 1974 %cmp = fcmp nnan uge <8 x float> %fs, zeroinitializer 1975 ret <8 x i1> %cmp 1976} 1977 1978define <8 x i1> @fcmp_ule_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 1979; CHECK-LABEL: @fcmp_ule_fsub_const_nnan_vec( 1980; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ule <8 x float> [[X:%.*]], [[Y:%.*]] 1981; CHECK-NEXT: ret <8 x i1> [[CMP]] 1982; 1983 %fs = fsub nnan <8 x float> %x, %y 1984 %cmp = fcmp nnan ule <8 x float> %fs, zeroinitializer 1985 ret <8 x i1> %cmp 1986} 1987 1988define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 1989; CHECK-LABEL: @fcmp_ueq_fsub_const_nnan_vec( 1990; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq <8 x float> [[X:%.*]], [[Y:%.*]] 1991; CHECK-NEXT: ret <8 x i1> [[CMP]] 1992; 1993 %fs = fsub nnan <8 x float> %x, %y 1994 %cmp = fcmp nnan ueq <8 x float> %fs, zeroinitializer 1995 ret <8 x i1> %cmp 1996} 1997 1998define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 1999; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec( 2000; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge <8 x float> [[X:%.*]], [[Y:%.*]] 2001; CHECK-NEXT: ret <8 x i1> [[CMP]] 2002; 2003 %fs = fsub nnan <8 x float> %x, %y 2004 %cmp = fcmp nnan oge <8 x float> %fs, zeroinitializer 2005 ret <8 x i1> %cmp 2006} 2007 2008define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2009; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec( 2010; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ole <8 x float> [[X:%.*]], [[Y:%.*]] 2011; CHECK-NEXT: ret <8 x i1> [[CMP]] 2012; 2013 %fs = fsub nnan <8 x float> %x, %y 2014 %cmp = fcmp nnan ole <8 x float> %fs, zeroinitializer 2015 ret <8 x i1> %cmp 2016} 2017 2018define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2019; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec( 2020; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[X:%.*]], [[Y:%.*]] 2021; CHECK-NEXT: ret <8 x i1> [[CMP]] 2022; 2023 %fs = fsub nnan <8 x float> %x, %y 2024 %cmp = fcmp nnan oeq <8 x float> %fs, zeroinitializer 2025 ret <8 x i1> %cmp 2026} 2027 2028define <8 x i1> @fcmp_ogt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2029; CHECK-LABEL: @fcmp_ogt_fsub_const_nnan_vec( 2030; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt <8 x float> [[X:%.*]], [[Y:%.*]] 2031; CHECK-NEXT: ret <8 x i1> [[CMP]] 2032; 2033 %fs = fsub nnan <8 x float> %x, %y 2034 %cmp = fcmp nnan ogt <8 x float> %fs, zeroinitializer 2035 ret <8 x i1> %cmp 2036} 2037 2038define <8 x i1> @fcmp_olt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2039; CHECK-LABEL: @fcmp_olt_fsub_const_nnan_vec( 2040; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan olt <8 x float> [[X:%.*]], [[Y:%.*]] 2041; CHECK-NEXT: ret <8 x i1> [[CMP]] 2042; 2043 %fs = fsub nnan <8 x float> %x, %y 2044 %cmp = fcmp nnan olt <8 x float> %fs, zeroinitializer 2045 ret <8 x i1> %cmp 2046} 2047 2048define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2049; CHECK-LABEL: @fcmp_one_fsub_const_nnan_vec( 2050; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one <8 x float> [[X:%.*]], [[Y:%.*]] 2051; CHECK-NEXT: ret <8 x i1> [[CMP]] 2052; 2053 %fs = fsub nnan <8 x float> %x, %y 2054 %cmp = fcmp nnan one <8 x float> %fs, zeroinitializer 2055 ret <8 x i1> %cmp 2056} 2057 2058define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2059; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec( 2060; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[X:%.*]], [[Y:%.*]] 2061; CHECK-NEXT: ret <8 x i1> [[CMP]] 2062; 2063 %fs = fsub nnan <8 x float> %x, %y 2064 %cmp = fcmp nnan ugt <8 x float> %fs, zeroinitializer 2065 ret <8 x i1> %cmp 2066} 2067 2068define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2069; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec( 2070; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ult <8 x float> [[X:%.*]], [[Y:%.*]] 2071; CHECK-NEXT: ret <8 x i1> [[CMP]] 2072; 2073 %fs = fsub nnan <8 x float> %x, %y 2074 %cmp = fcmp nnan ult <8 x float> %fs, zeroinitializer 2075 ret <8 x i1> %cmp 2076} 2077 2078define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) { 2079; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec( 2080; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan une <8 x float> [[X:%.*]], [[Y:%.*]] 2081; CHECK-NEXT: ret <8 x i1> [[CMP]] 2082; 2083 %fs = fsub nnan <8 x float> %x, %y 2084 %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer 2085 ret <8 x i1> %cmp 2086} 2087 2088define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero,positive-zero" { 2089; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero( 2090; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]] 2091; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer 2092; CHECK-NEXT: ret <8 x i1> [[CMP]] 2093; 2094 %fs = fsub <8 x float> %x, %y 2095 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer 2096 ret <8 x i1> %cmp 2097} 2098 2099define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="dynamic,dynamic" { 2100; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_dynamic( 2101; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]] 2102; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer 2103; CHECK-NEXT: ret <8 x i1> [[CMP]] 2104; 2105 %fs = fsub <8 x float> %x, %y 2106 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer 2107 ret <8 x i1> %cmp 2108} 2109 2110define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign,preserve-sign" { 2111; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign( 2112; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]] 2113; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer 2114; CHECK-NEXT: ret <8 x i1> [[CMP]] 2115; 2116 %fs = fsub <8 x float> %x, %y 2117 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer 2118 ret <8 x i1> %cmp 2119} 2120 2121define i1 @fcmp_sqrt_zero_olt(half %x) { 2122; CHECK-LABEL: @fcmp_sqrt_zero_olt( 2123; CHECK-NEXT: ret i1 false 2124; 2125 %sqrt = call half @llvm.sqrt.f16(half %x) 2126 %cmp = fcmp olt half %sqrt, 0.0 2127 ret i1 %cmp 2128} 2129 2130define i1 @fcmp_sqrt_zero_ult(half %x) { 2131; CHECK-LABEL: @fcmp_sqrt_zero_ult( 2132; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000 2133; CHECK-NEXT: ret i1 [[CMP]] 2134; 2135 %sqrt = call half @llvm.sqrt.f16(half %x) 2136 %cmp = fcmp ult half %sqrt, 0.0 2137 ret i1 %cmp 2138} 2139 2140define i1 @fcmp_sqrt_zero_ult_fmf(half %x) { 2141; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf( 2142; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ult half [[X:%.*]], 0xH0000 2143; CHECK-NEXT: ret i1 [[CMP]] 2144; 2145 %sqrt = call half @llvm.sqrt.f16(half %x) 2146 %cmp = fcmp ninf nsz ult half %sqrt, 0.0 2147 ret i1 %cmp 2148} 2149 2150define i1 @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(half %x) { 2151; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf_sqrt_ninf( 2152; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf nsz ult half [[X:%.*]], 0xH0000 2153; CHECK-NEXT: ret i1 [[CMP]] 2154; 2155 %sqrt = call ninf half @llvm.sqrt.f16(half %x) 2156 %cmp = fcmp ninf nsz ult half %sqrt, 0.0 2157 ret i1 %cmp 2158} 2159 2160define i1 @fcmp_sqrt_zero_ult_nzero(half %x) { 2161; CHECK-LABEL: @fcmp_sqrt_zero_ult_nzero( 2162; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000 2163; CHECK-NEXT: ret i1 [[CMP]] 2164; 2165 %sqrt = call half @llvm.sqrt.f16(half %x) 2166 %cmp = fcmp ult half %sqrt, -0.0 2167 ret i1 %cmp 2168} 2169 2170define <2 x i1> @fcmp_sqrt_zero_ult_vec(<2 x half> %x) { 2171; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec( 2172; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer 2173; CHECK-NEXT: ret <2 x i1> [[CMP]] 2174; 2175 %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x) 2176 %cmp = fcmp ult <2 x half> %sqrt, zeroinitializer 2177 ret <2 x i1> %cmp 2178} 2179 2180define <2 x i1> @fcmp_sqrt_zero_ult_vec_mixed_zero(<2 x half> %x) { 2181; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec_mixed_zero( 2182; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer 2183; CHECK-NEXT: ret <2 x i1> [[CMP]] 2184; 2185 %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x) 2186 %cmp = fcmp ult <2 x half> %sqrt, <half 0.0, half -0.0> 2187 ret <2 x i1> %cmp 2188} 2189 2190define i1 @fcmp_sqrt_zero_ole(half %x) { 2191; CHECK-LABEL: @fcmp_sqrt_zero_ole( 2192; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 2193; CHECK-NEXT: ret i1 [[CMP]] 2194; 2195 %sqrt = call half @llvm.sqrt.f16(half %x) 2196 %cmp = fcmp ole half %sqrt, 0.0 2197 ret i1 %cmp 2198} 2199 2200define i1 @fcmp_sqrt_zero_ule(half %x) { 2201; CHECK-LABEL: @fcmp_sqrt_zero_ule( 2202; CHECK-NEXT: [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000 2203; CHECK-NEXT: ret i1 [[CMP]] 2204; 2205 %sqrt = call half @llvm.sqrt.f16(half %x) 2206 %cmp = fcmp ule half %sqrt, 0.0 2207 ret i1 %cmp 2208} 2209 2210define i1 @fcmp_sqrt_zero_ogt(half %x) { 2211; CHECK-LABEL: @fcmp_sqrt_zero_ogt( 2212; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000 2213; CHECK-NEXT: ret i1 [[CMP]] 2214; 2215 %sqrt = call half @llvm.sqrt.f16(half %x) 2216 %cmp = fcmp ogt half %sqrt, 0.0 2217 ret i1 %cmp 2218} 2219 2220define i1 @fcmp_sqrt_zero_ugt(half %x) { 2221; CHECK-LABEL: @fcmp_sqrt_zero_ugt( 2222; CHECK-NEXT: [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000 2223; CHECK-NEXT: ret i1 [[CMP]] 2224; 2225 %sqrt = call half @llvm.sqrt.f16(half %x) 2226 %cmp = fcmp ugt half %sqrt, 0.0 2227 ret i1 %cmp 2228} 2229 2230define i1 @fcmp_sqrt_zero_oge(half %x) { 2231; CHECK-LABEL: @fcmp_sqrt_zero_oge( 2232; CHECK-NEXT: [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000 2233; CHECK-NEXT: ret i1 [[CMP]] 2234; 2235 %sqrt = call half @llvm.sqrt.f16(half %x) 2236 %cmp = fcmp oge half %sqrt, 0.0 2237 ret i1 %cmp 2238} 2239 2240define i1 @fcmp_sqrt_zero_uge(half %x) { 2241; CHECK-LABEL: @fcmp_sqrt_zero_uge( 2242; CHECK-NEXT: ret i1 true 2243; 2244 %sqrt = call half @llvm.sqrt.f16(half %x) 2245 %cmp = fcmp uge half %sqrt, 0.0 2246 ret i1 %cmp 2247} 2248 2249define i1 @fcmp_sqrt_zero_oeq(half %x) { 2250; CHECK-LABEL: @fcmp_sqrt_zero_oeq( 2251; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 2252; CHECK-NEXT: ret i1 [[CMP]] 2253; 2254 %sqrt = call half @llvm.sqrt.f16(half %x) 2255 %cmp = fcmp oeq half %sqrt, 0.0 2256 ret i1 %cmp 2257} 2258 2259define i1 @fcmp_sqrt_zero_ueq(half %x) { 2260; CHECK-LABEL: @fcmp_sqrt_zero_ueq( 2261; CHECK-NEXT: [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000 2262; CHECK-NEXT: ret i1 [[CMP]] 2263; 2264 %sqrt = call half @llvm.sqrt.f16(half %x) 2265 %cmp = fcmp ueq half %sqrt, 0.0 2266 ret i1 %cmp 2267} 2268 2269define i1 @fcmp_sqrt_zero_one(half %x) { 2270; CHECK-LABEL: @fcmp_sqrt_zero_one( 2271; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000 2272; CHECK-NEXT: ret i1 [[CMP]] 2273; 2274 %sqrt = call half @llvm.sqrt.f16(half %x) 2275 %cmp = fcmp one half %sqrt, 0.0 2276 ret i1 %cmp 2277} 2278 2279define i1 @fcmp_sqrt_zero_une(half %x) { 2280; CHECK-LABEL: @fcmp_sqrt_zero_une( 2281; CHECK-NEXT: [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000 2282; CHECK-NEXT: ret i1 [[CMP]] 2283; 2284 %sqrt = call half @llvm.sqrt.f16(half %x) 2285 %cmp = fcmp une half %sqrt, 0.0 2286 ret i1 %cmp 2287} 2288 2289define i1 @fcmp_sqrt_zero_ord(half %x) { 2290; CHECK-LABEL: @fcmp_sqrt_zero_ord( 2291; CHECK-NEXT: [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000 2292; CHECK-NEXT: ret i1 [[CMP]] 2293; 2294 %sqrt = call half @llvm.sqrt.f16(half %x) 2295 %cmp = fcmp ord half %sqrt, 0.0 2296 ret i1 %cmp 2297} 2298 2299define i1 @fcmp_sqrt_zero_uno(half %x) { 2300; CHECK-LABEL: @fcmp_sqrt_zero_uno( 2301; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000 2302; CHECK-NEXT: ret i1 [[CMP]] 2303; 2304 %sqrt = call half @llvm.sqrt.f16(half %x) 2305 %cmp = fcmp uno half %sqrt, 0.0 2306 ret i1 %cmp 2307} 2308 2309; Make sure that ninf is cleared. 2310define i1 @fcmp_sqrt_zero_uno_fmf(half %x) { 2311; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf( 2312; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000 2313; CHECK-NEXT: ret i1 [[CMP]] 2314; 2315 %sqrt = call half @llvm.sqrt.f16(half %x) 2316 %cmp = fcmp ninf uno half %sqrt, 0.0 2317 ret i1 %cmp 2318} 2319 2320define i1 @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(half %x) { 2321; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf_sqrt_ninf( 2322; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ult half [[X:%.*]], 0xH0000 2323; CHECK-NEXT: ret i1 [[CMP]] 2324; 2325 %sqrt = call ninf half @llvm.sqrt.f16(half %x) 2326 %cmp = fcmp ninf uno half %sqrt, 0.0 2327 ret i1 %cmp 2328} 2329 2330; negative tests 2331 2332define i1 @fcmp_sqrt_zero_ult_var(half %x, half %y) { 2333; CHECK-LABEL: @fcmp_sqrt_zero_ult_var( 2334; CHECK-NEXT: [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]]) 2335; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[SQRT]], [[Y:%.*]] 2336; CHECK-NEXT: ret i1 [[CMP]] 2337; 2338 %sqrt = call half @llvm.sqrt.f16(half %x) 2339 %cmp = fcmp ult half %sqrt, %y 2340 ret i1 %cmp 2341} 2342 2343define i1 @fcmp_sqrt_zero_ult_nonzero(half %x) { 2344; CHECK-LABEL: @fcmp_sqrt_zero_ult_nonzero( 2345; CHECK-NEXT: [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]]) 2346; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[SQRT]], 0xH3C00 2347; CHECK-NEXT: ret i1 [[CMP]] 2348; 2349 %sqrt = call half @llvm.sqrt.f16(half %x) 2350 %cmp = fcmp ult half %sqrt, 1.000000e+00 2351 ret i1 %cmp 2352} 2353