brintos

brintos / llvm-project-archived public Read only

0
0
Text · 73.5 KiB · d94e78c Raw
2393 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 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 double18  %ext2 = fpext float %y to double19  %cmp = fcmp nnan ogt double %ext1, %ext220  ret i1 %cmp21}22 23define i1 @fpext_constant(float %a) {24; CHECK-LABEL: @fpext_constant(25; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt float [[A:%.*]], 1.000000e+0026; CHECK-NEXT:    ret i1 [[CMP]]27;28  %ext = fpext float %a to double29  %cmp = fcmp ninf ogt double %ext, 1.000000e+0030  ret i1 %cmp31}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> %cmp41}42 43define i1 @fpext_constant_lossy(float %a) {44; CHECK-LABEL: @fpext_constant_lossy(45; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double46; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF000000000000147; CHECK-NEXT:    ret i1 [[CMP]]48;49  %ext = fpext float %a to double50  %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.51  ret i1 %cmp52}53 54define i1 @fpext_constant_denorm(float %a) {55; CHECK-LABEL: @fpext_constant_denorm(56; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double57; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A000000000000058; CHECK-NEXT:    ret i1 [[CMP]]59;60  %ext = fpext float %a to double61  %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.62  ret i1 %cmp63}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+0068; CHECK-NEXT:    ret i1 [[CMP]]69;70  %neg = fsub float -0.0, %x71  %cmp = fcmp ogt float %neg, 1.072  ret i1 %cmp73}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+0078; CHECK-NEXT:    ret i1 [[CMP]]79;80  %neg = fneg float %x81  %cmp = fcmp ogt float %neg, 1.082  ret i1 %cmp83}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>, %x91  %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>92  ret <2 x i1> %cmp93}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> %x101  %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>102  ret <2 x i1> %cmp103}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>, %x111  %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>112  ret <2 x i1> %cmp113}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+01120; CHECK-NEXT:    ret i1 [[R]]121;122  %n = fsub fast float -0.0, %x123  %r = fcmp fast oeq float %n, 42.0124  ret i1 %r125}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+01130; CHECK-NEXT:    ret i1 [[R]]131;132  %n = fneg fast float %x133  %r = fcmp fast oeq float %n, 42.0134  ret i1 %r135}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, %x145  %r = fcmp nnan reassoc uge <2 x float> %n, <float 42.0, float -19.0>146  ret <2 x i1> %r147}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, %x155  %neg2 = fsub float -0.0, %y156  %cmp = fcmp nnan olt float %neg1, %neg2157  ret i1 %cmp158}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 %x166  %neg2 = fneg float %y167  %cmp = fcmp nnan olt float %neg1, %neg2168  ret i1 %cmp169}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 %x177  %neg2 = fsub float -0.0, %y178  %cmp = fcmp nnan olt float %neg1, %neg2179  ret i1 %cmp180}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, %x188  %neg2 = fneg float %y189  %cmp = fcmp nnan olt float %neg1, %neg2190  ret i1 %cmp191}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>, %x199  %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y200  %cmp = fcmp ninf olt <2 x float> %neg1, %neg2201  ret <2 x i1> %cmp202}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> %x210  %neg2 = fneg <2 x float> %y211  %cmp = fcmp ninf olt <2 x float> %neg1, %neg2212  ret <2 x i1> %cmp213}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> %x221  %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y222  %cmp = fcmp ninf olt <2 x float> %neg1, %neg2223  ret <2 x i1> %cmp224}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>, %x232  %neg2 = fneg <2 x float> %y233  %cmp = fcmp ninf olt <2 x float> %neg1, %neg2234  ret <2 x i1> %cmp235}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>, %x243  %neg2 = fsub <2 x float> <float poison, float -0.0>, %y244  %cmp = fcmp olt <2 x float> %neg1, %neg2245  ret <2 x i1> %cmp246}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> %x254  %neg2 = fsub <2 x float> <float poison, float -0.0>, %y255  %cmp = fcmp olt <2 x float> %neg1, %neg2256  ret <2 x i1> %cmp257}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>, %x265  %neg2 = fneg <2 x float> %y266  %cmp = fcmp olt <2 x float> %neg1, %neg2267  ret <2 x i1> %cmp268}269 270define i1 @test7(float %x) {271; CHECK-LABEL: @test7(272; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00273; CHECK-NEXT:    ret i1 [[CMP]]274;275  %ext = fpext float %x to ppc_fp128276  %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000277  ret i1 %cmp278}279 280define float @test8(float %x) {281; CHECK-LABEL: @test8(282; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00283; CHECK-NEXT:    [[CONV2:%.*]] = uitofp i1 [[CMP]] to float284; CHECK-NEXT:    ret float [[CONV2]]285;286  %conv = fpext float %x to double287  %cmp = fcmp olt double %conv, 0.000000e+00288  %conv1 = zext i1 %cmp to i32289  %conv2 = sitofp i32 %conv1 to float290  ret float %conv2291; 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 true297;298  %call = call double @llvm.fabs.f64(double %a)299  %cmp = fcmp uge double %call, 0.0300  ret i1 %cmp301}302 303define i1 @fabs_olt(half %a) {304; CHECK-LABEL: @fabs_olt(305; CHECK-NEXT:    ret i1 false306;307  %call = call half @llvm.fabs.f16(half %a)308  %cmp = fcmp olt half %call, 0.0309  ret i1 %cmp310}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:%.*]], zeroinitializer315; 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, zeroinitializer319  ret <2 x i1> %cmp320}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:%.*]], zeroinitializer325; 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, zeroinitializer329  ret <2 x i1> %cmp330}331 332define i1 @fabs_ogt(double %a) {333; CHECK-LABEL: @fabs_ogt(334; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc one double [[A:%.*]], 0.000000e+00335; CHECK-NEXT:    ret i1 [[CMP]]336;337  %call = call double @llvm.fabs.f64(double %a)338  %cmp = fcmp reassoc ogt double %call, 0.0339  ret i1 %cmp340}341 342define i1 @fabs_ugt(double %a) {343; CHECK-LABEL: @fabs_ugt(344; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc ninf une double [[A:%.*]], 0.000000e+00345; CHECK-NEXT:    ret i1 [[CMP]]346;347  %call = call double @llvm.fabs.f64(double %a)348  %cmp = fcmp ninf reassoc ugt double %call, 0.0349  ret i1 %cmp350}351 352define i1 @fabs_oge(double %a) {353; CHECK-LABEL: @fabs_oge(354; CHECK-NEXT:    [[CMP:%.*]] = fcmp afn ord double [[A:%.*]], 0.000000e+00355; CHECK-NEXT:    ret i1 [[CMP]]356;357  %call = call double @llvm.fabs.f64(double %a)358  %cmp = fcmp afn oge double %call, 0.0359  ret i1 %cmp360}361 362define i1 @fabs_ult(double %a) {363; CHECK-LABEL: @fabs_ult(364; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc arcp uno double [[A:%.*]], 0.000000e+00365; CHECK-NEXT:    ret i1 [[CMP]]366;367  %call = call double @llvm.fabs.f64(double %a)368  %cmp = fcmp reassoc arcp ult double %call, 0.0369  ret i1 %cmp370}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> zeroinitializer375;376  %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)377  %cmp = fcmp nnan reassoc arcp ult <2 x float> %call, zeroinitializer378  ret <2 x i1> %cmp379}380 381define i1 @fabs_une(half %a) {382; CHECK-LABEL: @fabs_une(383; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une half [[A:%.*]], 0xH0000384; CHECK-NEXT:    ret i1 [[CMP]]385;386  %call = call half @llvm.fabs.f16(half %a)387  %cmp = fcmp ninf une half %call, 0.0388  ret i1 %cmp389}390 391define i1 @fabs_oeq(double %a) {392; CHECK-LABEL: @fabs_oeq(393; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc ninf oeq double [[A:%.*]], 0.000000e+00394; CHECK-NEXT:    ret i1 [[CMP]]395;396  %call = call double @llvm.fabs.f64(double %a)397  %cmp = fcmp ninf reassoc oeq double %call, 0.0398  ret i1 %cmp399}400 401define i1 @fabs_one(double %a) {402; CHECK-LABEL: @fabs_one(403; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast one double [[A:%.*]], 0.000000e+00404; CHECK-NEXT:    ret i1 [[CMP]]405;406  %call = call double @llvm.fabs.f64(double %a)407  %cmp = fcmp fast one double %call, 0.0408  ret i1 %cmp409}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:%.*]], zeroinitializer414; 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, zeroinitializer418  ret <2 x i1> %cmp419}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:%.*]], zeroinitializer424; 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, zeroinitializer428  ret <2 x i1> %cmp429}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:%.*]], zeroinitializer434; 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, zeroinitializer438  ret <2 x i1> %cmp439}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+00446; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32447; CHECK-NEXT:    ret i32 [[CONV]]448;449  %call = tail call double %p(double %a)450  %cmp = fcmp ueq double %call, 0.000000e+00451  %conv = zext i1 %cmp to i32452  ret i32 %conv453}454 455; Can fold fcmp with undef on one side by choosing NaN for the undef456define i32 @test18_undef_unordered(float %a) {457; CHECK-LABEL: @test18_undef_unordered(458; CHECK-NEXT:    ret i32 1459;460  %cmp = fcmp ueq float %a, undef461  %conv = zext i1 %cmp to i32462  ret i32 %conv463}464; Can fold fcmp with undef on one side by choosing NaN for the undef465define i32 @test18_undef_ordered(float %a) {466; CHECK-LABEL: @test18_undef_ordered(467; CHECK-NEXT:    ret i32 0468;469  %cmp = fcmp oeq float %a, undef470  %conv = zext i1 %cmp to i32471  ret i32 %conv472}473 474; Can fold fcmp with undef on both side475;   fcmp u_pred undef, undef -> true476;   fcmp o_pred undef, undef -> false477; because whatever you choose for the first undef478; you can choose NaN for the other undef479define i1 @test19_undef_unordered() {480; CHECK-LABEL: @test19_undef_unordered(481; CHECK-NEXT:    ret i1 true482;483  %cmp = fcmp ueq float undef, undef484  ret i1 %cmp485}486 487define i1 @test19_undef_ordered() {488; CHECK-LABEL: @test19_undef_ordered(489; CHECK-NEXT:    ret i1 false490;491  %cmp = fcmp oeq float undef, undef492  ret i1 %cmp493}494 495; Can fold 1.0 / X < 0.0 --> X < 0 with ninf496define 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+00499; CHECK-NEXT:    ret i1 [[CMP]]500;501  %div = fdiv ninf float 1.0, %X502  %cmp = fcmp ninf olt float %div, 0.0503  ret i1 %cmp504}505 506; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf507define 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+00510; CHECK-NEXT:    ret i1 [[CMP]]511;512  %div = fdiv ninf float -2.0, %X513  %cmp = fcmp ninf ole float %div, 0.0514  ret i1 %cmp515}516 517; Can fold 2.0 / X > 0.0 --> X > 0 with ninf518define 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+00521; CHECK-NEXT:    ret i1 [[CMP]]522;523  %div = fdiv ninf float 2.0, %X524  %cmp = fcmp ninf ogt float %div, 0.0525  ret i1 %cmp526}527 528; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf529define 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+00532; CHECK-NEXT:    ret i1 [[CMP]]533;534  %div = fdiv ninf float -1.0, %X535  %cmp = fcmp ninf oge float %div, 0.0536  ret i1 %cmp537}538 539; Do not fold 1.0 / X > 0.0 when ninf is missing540define 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+00544; CHECK-NEXT:    ret i1 [[CMP]]545;546  %div = fdiv ninf float 2.0, %X547  %cmp = fcmp ogt float %div, 0.0548  ret i1 %cmp549}550 551; Do not fold 1.0 / X > 0.0 when ninf is missing552define 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+00556; CHECK-NEXT:    ret i1 [[CMP]]557;558  %div = fdiv float 2.0, %X559  %cmp = fcmp ninf ogt float %div, 0.0560  ret i1 %cmp561}562 563; Do not fold 1.0 / X > 0.0 with unordered predicates564define 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+00568; CHECK-NEXT:    ret i1 [[CMP]]569;570  %div = fdiv ninf float 2.0, %X571  %cmp = fcmp ninf ugt float %div, 0.0572  ret i1 %cmp573}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:%.*]], zeroinitializer579; CHECK-NEXT:    ret <2 x i1> [[CMP]]580;581  %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X582  %cmp = fcmp ninf ogt <2 x float> %div, <float -0.0, float -0.0>583  ret <2 x i1> %cmp584}585 586define i1 @is_signbit_set(double %x) {587; CHECK-LABEL: @is_signbit_set(588; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64589; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[TMP1]], 0590; 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.0594  ret i1 %r595}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+00601; 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.0605  ret i1 %r606}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+00612; 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.0616  ret i1 %r617}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+00623; 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.0627  ret i1 %r628}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]], zeroinitializer636; 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> %r641}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+00649; 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.0653  ret i1 %r654}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+00660; 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.0664  ret i1 %r665}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+00671; 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.0675  ret i1 %r676}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+00682; 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.0686  ret i1 %r687}688 689; Negative test - uses690 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 8695; CHECK-NEXT:    [[R:%.*]] = fcmp olt double [[S]], 0.000000e+00696; CHECK-NEXT:    ret i1 [[R]]697;698  %s = call double @llvm.copysign.f64(double 1.0, double %x)699  store double %s, ptr %p700  %r = fcmp olt double %s, 0.0701  ret i1 %r702}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+00710; 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.0714  ret i1 %r715}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 false722;723  %s = call double @llvm.copysign.f64(double 0.0, double %x)724  %r = fcmp ogt double %s, 0.0725  ret i1 %r726}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 false733;734  %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)735  %r = fcmp ogt double %s, 0.0736  ret i1 %r737}738 739define <2 x i1> @lossy_oeq(<2 x float> %x) {740; CHECK-LABEL: @lossy_oeq(741; CHECK-NEXT:    ret <2 x i1> zeroinitializer742;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> %r746}747 748define i1 @lossy_one(float %x, ptr %p) {749; CHECK-LABEL: @lossy_one(750; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double751; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8752; CHECK-NEXT:    [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00753; CHECK-NEXT:    ret i1 [[R]]754;755  %e = fpext float %x to double756  store double %e, ptr %p757  %r = fcmp one double %e, 0.1758  ret i1 %r759}760 761define i1 @lossy_ueq(half %x) {762; CHECK-LABEL: @lossy_ueq(763; CHECK-NEXT:    [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000764; CHECK-NEXT:    ret i1 [[R]]765;766  %e = fpext half %x to double767  %r = fcmp ueq double %e, 65536.0768  ret i1 %r769}770 771define i1 @lossy_une(half %x) {772; CHECK-LABEL: @lossy_une(773; CHECK-NEXT:    ret i1 true774;775  %e = fpext half %x to float776  %r = fcmp une float %e, 2049.0777  ret i1 %r778}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> %r789}790 791define i1 @lossy_oge(float %x, ptr %p) {792; CHECK-LABEL: @lossy_oge(793; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double794; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8795; CHECK-NEXT:    [[R:%.*]] = fcmp oge double [[E]], 1.000000e-01796; CHECK-NEXT:    ret i1 [[R]]797;798  %e = fpext float %x to double799  store double %e, ptr %p800  %r = fcmp oge double %e, 0.1801  ret i1 %r802}803 804define i1 @lossy_olt(half %x) {805; CHECK-LABEL: @lossy_olt(806; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double807; CHECK-NEXT:    [[R:%.*]] = fcmp olt double [[E]], 6.553600e+04808; CHECK-NEXT:    ret i1 [[R]]809;810  %e = fpext half %x to double811  %r = fcmp olt double %e, 65536.0812  ret i1 %r813}814 815define i1 @lossy_ole(half %x) {816; CHECK-LABEL: @lossy_ole(817; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float818; CHECK-NEXT:    [[R:%.*]] = fcmp ole float [[E]], 2.049000e+03819; CHECK-NEXT:    ret i1 [[R]]820;821  %e = fpext half %x to float822  %r = fcmp ole float %e, 2049.0823  ret i1 %r824}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> %r835}836 837define i1 @lossy_uge(float %x, ptr %p) {838; CHECK-LABEL: @lossy_uge(839; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double840; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8841; CHECK-NEXT:    [[R:%.*]] = fcmp uge double [[E]], 1.000000e-01842; CHECK-NEXT:    ret i1 [[R]]843;844  %e = fpext float %x to double845  store double %e, ptr %p846  %r = fcmp uge double %e, 0.1847  ret i1 %r848}849 850define i1 @lossy_ult(half %x) {851; CHECK-LABEL: @lossy_ult(852; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double853; CHECK-NEXT:    [[R:%.*]] = fcmp ult double [[E]], 6.553600e+04854; CHECK-NEXT:    ret i1 [[R]]855;856  %e = fpext half %x to double857  %r = fcmp ult double %e, 65536.0858  ret i1 %r859}860 861define i1 @lossy_ule(half %x) {862; CHECK-LABEL: @lossy_ule(863; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float864; CHECK-NEXT:    [[R:%.*]] = fcmp ule float [[E]], 2.049000e+03865; CHECK-NEXT:    ret i1 [[R]]866;867  %e = fpext half %x to float868  %r = fcmp ule float %e, 2049.0869  ret i1 %r870}871 872define i1 @lossy_ord(half %x) {873; CHECK-LABEL: @lossy_ord(874; CHECK-NEXT:    [[R:%.*]] = fcmp ord half [[X:%.*]], 0xH0000875; CHECK-NEXT:    ret i1 [[R]]876;877  %e = fpext half %x to double878  %r = fcmp ord double %e, 65536.0879  ret i1 %r880}881 882define i1 @lossy_uno(half %x) {883; CHECK-LABEL: @lossy_uno(884; CHECK-NEXT:    [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000885; CHECK-NEXT:    ret i1 [[R]]886;887  %e = fpext half %x to float888  %r = fcmp uno float %e, 2049.0889  ret i1 %r890}891 892define i1 @fneg_oeq(float %a) {893; CHECK-LABEL: @fneg_oeq(894; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00895; CHECK-NEXT:    ret i1 [[CMP]]896;897  %fneg = fneg float %a898  %cmp = fcmp oeq float %fneg, %a899  ret i1 %cmp900}901 902define i1 @fneg_ogt(half %a) {903; CHECK-LABEL: @fneg_ogt(904; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000905; CHECK-NEXT:    ret i1 [[CMP]]906;907  %fneg = fneg half %a908  %cmp = fcmp fast ogt half %fneg, %a909  ret i1 %cmp910}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:%.*]], zeroinitializer915; CHECK-NEXT:    ret <2 x i1> [[CMP]]916;917  %fneg = fneg fast <2 x float> %a918  %cmp = fcmp oge <2 x float> %fneg, %a919  ret <2 x i1> %cmp920}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 4926; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00927; CHECK-NEXT:    ret i1 [[CMP]]928;929  %fneg = fneg float %a930  store float %fneg, ptr %q931  %cmp = fcmp olt float %fneg, %a932  ret i1 %cmp933}934 935define i1 @fneg_ole(float %a) {936; CHECK-LABEL: @fneg_ole(937; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00938; CHECK-NEXT:    ret i1 [[CMP]]939;940  %fneg = fneg float %a941  %cmp = fcmp nsz ole float %fneg, %a942  ret i1 %cmp943}944 945define i1 @fneg_one(float %a) {946; CHECK-LABEL: @fneg_one(947; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00948; CHECK-NEXT:    ret i1 [[CMP]]949;950  %fneg = fneg float %a951  %cmp = fcmp nnan one float %fneg, %a952  ret i1 %cmp953}954 955define i1 @fneg_ord(float %a) {956; CHECK-LABEL: @fneg_ord(957; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00958; CHECK-NEXT:    ret i1 [[CMP]]959;960  %fneg = fneg float %a961  %cmp = fcmp ninf ord float %fneg, %a962  ret i1 %cmp963}964 965define i1 @fneg_uno(float %a) {966; CHECK-LABEL: @fneg_uno(967; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00968; CHECK-NEXT:    ret i1 [[CMP]]969;970  %fneg = fneg float %a971  %cmp = fcmp uno float %fneg, %a972  ret i1 %cmp973}974 975define i1 @fneg_ueq(half %a) {976; CHECK-LABEL: @fneg_ueq(977; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000978; CHECK-NEXT:    ret i1 [[CMP]]979;980  %fneg = fneg half %a981  %cmp = fcmp fast ueq half %fneg, %a982  ret i1 %cmp983}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:%.*]], zeroinitializer988; CHECK-NEXT:    ret <2 x i1> [[CMP]]989;990  %fneg = fneg fast <2 x float> %a991  %cmp = fcmp ugt <2 x float> %fneg, %a992  ret <2 x i1> %cmp993}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 4999; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+001000; CHECK-NEXT:    ret i1 [[CMP]]1001;1002  %fneg = fneg float %a1003  store float %fneg, ptr %q1004  %cmp = fcmp uge float %fneg, %a1005  ret i1 %cmp1006}1007 1008define i1 @fneg_ult(float %a) {1009; CHECK-LABEL: @fneg_ult(1010; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+001011; CHECK-NEXT:    ret i1 [[CMP]]1012;1013  %fneg = fneg float %a1014  %cmp = fcmp nsz ult float %fneg, %a1015  ret i1 %cmp1016}1017 1018define i1 @fneg_ule(float %a) {1019; CHECK-LABEL: @fneg_ule(1020; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+001021; CHECK-NEXT:    ret i1 [[CMP]]1022;1023  %fneg = fneg float %a1024  %cmp = fcmp nnan ule float %fneg, %a1025  ret i1 %cmp1026}1027 1028define i1 @fneg_une(float %a) {1029; CHECK-LABEL: @fneg_une(1030; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+001031; CHECK-NEXT:    ret i1 [[CMP]]1032;1033  %fneg = fneg float %a1034  %cmp = fcmp ninf une float %fneg, %a1035  ret i1 %cmp1036}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+001042; CHECK-NEXT:    ret i1 [[CMP]]1043;1044  %a = fadd float %p, %p ; thwart complexity-based canonicalization1045  %fneg = fneg float %a1046  %cmp = fcmp oeq float %a, %fneg1047  ret i1 %cmp1048}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]], 0xH00001054; CHECK-NEXT:    ret i1 [[CMP]]1055;1056  %a = fadd half %p, %p ; thwart complexity-based canonicalization1057  %fneg = fneg half %a1058  %cmp = fcmp fast ogt half %a, %fneg1059  ret i1 %cmp1060}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]], zeroinitializer1066; CHECK-NEXT:    ret <2 x i1> [[CMP]]1067;1068  %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization1069  %fneg = fneg fast <2 x float> %a1070  %cmp = fcmp oge <2 x float> %a, %fneg1071  ret <2 x i1> %cmp1072}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 41079; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+001080; CHECK-NEXT:    ret i1 [[CMP]]1081;1082  %a = fadd float %p, %p ; thwart complexity-based canonicalization1083  %fneg = fneg float %a1084  store float %fneg, ptr %q1085  %cmp = fcmp olt float %a, %fneg1086  ret i1 %cmp1087}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+001093; CHECK-NEXT:    ret i1 [[CMP]]1094;1095  %a = fadd float %p, %p ; thwart complexity-based canonicalization1096  %fneg = fneg float %a1097  %cmp = fcmp nsz ole float %a, %fneg1098  ret i1 %cmp1099}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+001105; CHECK-NEXT:    ret i1 [[CMP]]1106;1107  %a = fadd float %p, %p ; thwart complexity-based canonicalization1108  %fneg = fneg float %a1109  %cmp = fcmp nnan one float %a, %fneg1110  ret i1 %cmp1111}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+001117; CHECK-NEXT:    ret i1 [[CMP]]1118;1119  %a = fadd float %p, %p ; thwart complexity-based canonicalization1120  %fneg = fneg float %a1121  %cmp = fcmp ninf ord float %a, %fneg1122  ret i1 %cmp1123}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+001129; CHECK-NEXT:    ret i1 [[CMP]]1130;1131  %a = fadd float %p, %p ; thwart complexity-based canonicalization1132  %fneg = fneg float %a1133  %cmp = fcmp uno float %a, %fneg1134  ret i1 %cmp1135}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]], 0xH00001141; CHECK-NEXT:    ret i1 [[CMP]]1142;1143  %a = fadd half %p, %p ; thwart complexity-based canonicalization1144  %fneg = fneg half %a1145  %cmp = fcmp fast ueq half %a, %fneg1146  ret i1 %cmp1147}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]], zeroinitializer1153; CHECK-NEXT:    ret <2 x i1> [[CMP]]1154;1155  %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization1156  %fneg = fneg fast <2 x float> %a1157  %cmp = fcmp ugt <2 x float> %a, %fneg1158  ret <2 x i1> %cmp1159}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 41166; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+001167; CHECK-NEXT:    ret i1 [[CMP]]1168;1169  %a = fadd float %p, %p ; thwart complexity-based canonicalization1170  %fneg = fneg float %a1171  store float %fneg, ptr %q1172  %cmp = fcmp uge float %a, %fneg1173  ret i1 %cmp1174}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+001180; CHECK-NEXT:    ret i1 [[CMP]]1181;1182  %a = fadd float %p, %p ; thwart complexity-based canonicalization1183  %fneg = fneg float %a1184  %cmp = fcmp nsz ult float %a, %fneg1185  ret i1 %cmp1186}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+001192; CHECK-NEXT:    ret i1 [[CMP]]1193;1194  %a = fadd float %p, %p ; thwart complexity-based canonicalization1195  %fneg = fneg float %a1196  %cmp = fcmp nnan ule float %a, %fneg1197  ret i1 %cmp1198}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+001204; CHECK-NEXT:    ret i1 [[CMP]]1205;1206  %a = fadd float %p, %p ; thwart complexity-based canonicalization1207  %fneg = fneg float %a1208  %cmp = fcmp ninf une float %a, %fneg1209  ret i1 %cmp1210}1211 1212define i1 @bitcast_eq0(i32 %x) {1213; CHECK-LABEL: @bitcast_eq0(1214; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 21474836471215; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 01216; CHECK-NEXT:    ret i1 [[R]]1217;1218  %f = bitcast i32 %x to float1219  %r = fcmp oeq float %f, 0.01220  ret i1 %r1221}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]], zeroinitializer1227; 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> %r1232}1233 1234; negative test - extra use1235 1236define i1 @bitcast_eq0_use(i32 %x) {1237; CHECK-LABEL: @bitcast_eq0_use(1238; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float1239; CHECK-NEXT:    call void @use(float [[F]])1240; CHECK-NEXT:    [[R:%.*]] = fcmp oeq float [[F]], 0.000000e+001241; CHECK-NEXT:    ret i1 [[R]]1242;1243  %f = bitcast i32 %x to float1244  call void @use(float %f)1245  %r = fcmp oeq float %f, 0.01246  ret i1 %r1247}1248 1249; negative test - this could be transformed, but requires a new bitcast1250 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 float1254; CHECK-NEXT:    [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+001255; CHECK-NEXT:    ret i1 [[R]]1256;1257  %f = bitcast <2 x i16> %x to float1258  %r = fcmp ogt float %f, 0.01259  ret i1 %r1260}1261 1262; negative test - wrong predicate1263 1264define i1 @bitcast_gt0(i32 %x) {1265; CHECK-LABEL: @bitcast_gt0(1266; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float1267; CHECK-NEXT:    [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+001268; CHECK-NEXT:    ret i1 [[R]]1269;1270  %f = bitcast i32 %x to float1271  %r = fcmp ogt float %f, 0.01272  ret i1 %r1273}1274 1275; negative test - this could be transformed, but requires a new bitcast1276 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]], zeroinitializer1281; 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, zeroinitializer1285  ret <1 x i1> %cmp1286}1287 1288; Simplify fcmp (x + 0.0), y => fcmp x, y1289 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+001296  %cmp = fcmp ugt float %add, %y1297  ret i1 %cmp1298}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+001306  %cmp = fcmp uge float %add, %y1307  ret i1 %cmp1308}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+001316  %cmp = fcmp ogt float %add, %y1317  ret i1 %cmp1318}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+001326  %cmp = fcmp oge float %add, %y1327  ret i1 %cmp1328}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+001336  %cmp = fcmp ult float %add, %y1337  ret i1 %cmp1338}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+001346  %cmp = fcmp ule float %add, %y1347  ret i1 %cmp1348}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+001356  %cmp = fcmp olt float %add, %y1357  ret i1 %cmp1358}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+001366  %cmp = fcmp ole float %add, %y1367  ret i1 %cmp1368}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+001376  %cmp = fcmp oeq float %add, %y1377  ret i1 %cmp1378}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+001386  %cmp = fcmp one float %add, %y1387  ret i1 %cmp1388}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+001396  %cmp = fcmp ueq float %add, %y1397  ret i1 %cmp1398}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+001406  %cmp = fcmp une float %add, %y1407  ret i1 %cmp1408}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+001416  %cmp = fcmp ord float %add, %y1417  ret i1 %cmp1418}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+001426  %cmp = fcmp uno float %add, %y1427  ret i1 %cmp1428}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+001436  %cmp = fcmp ugt float %add, %y1437  ret i1 %cmp1438}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+001446  %cmp = fcmp ugt float %x, %add1447  ret i1 %cmp1448}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, %y1457  ret <2 x i1> %cmp1458}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+001466  %cmp = fcmp fast ugt float %add, %y1467  ret i1 %cmp1468}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+001476  %cmp = fcmp fast ugt float %add, %y1477  ret i1 %cmp1478}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+001486  %cmp = fcmp ugt float %add, %y1487  ret i1 %cmp1488}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+001493; CHECK-NEXT:    ret i1 [[RES]]1494;1495  %f = fcmp ueq float %x, 0.000000e+001496  %neg = fneg float %x1497  %sel = select i1 %f, float %x, float %neg1498  %res = fcmp ueq float %sel, 0.000000e+001499  ret i1 %res1500}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+001505; CHECK-NEXT:    ret i1 [[RES]]1506;1507  %f = fcmp une float %x, 0.000000e+001508  %neg = fneg float %x1509  %sel = select i1 %f, float %x, float %neg1510  %res = fcmp une float %sel, 0.000000e+001511  ret i1 %res1512}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+001517; CHECK-NEXT:    ret i1 [[RES]]1518;1519  %f = fcmp oeq float %x, 0.000000e+001520  %neg = fneg float %x1521  %sel = select i1 %f, float %x, float %neg1522  %res = fcmp oeq float %sel, 0.000000e+001523  ret i1 %res1524}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+001529; CHECK-NEXT:    ret i1 [[RES]]1530;1531  %f = fcmp one float %x, 0.000000e+001532  %neg = fneg float %x1533  %sel = select i1 %f, float %x, float %neg1534  %res = fcmp one float %sel, 0.000000e+001535  ret i1 %res1536}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+001541; CHECK-NEXT:    ret i1 [[RES]]1542;1543  %f = fcmp ueq float %x, 0.000000e+001544  %neg = fneg float %x1545  %sel = select i1 %f, float %x, float %neg1546  %res = fcmp ueq float %sel, -0.000000e+001547  ret i1 %res1548}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+001553; CHECK-NEXT:    ret i1 [[RES]]1554;1555  %f = fcmp une float %x, 0.000000e+001556  %neg = fneg float %x1557  %sel = select i1 %f, float %x, float %neg1558  %res = fcmp une float %sel, -0.000000e+001559  ret i1 %res1560}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+001565; CHECK-NEXT:    ret i1 [[RES]]1566;1567  %f = fcmp oeq float %x, 0.000000e+001568  %neg = fneg float %x1569  %sel = select i1 %f, float %x, float %neg1570  %res = fcmp oeq float %sel, -0.000000e+001571  ret i1 %res1572}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+001577; CHECK-NEXT:    ret i1 [[RES]]1578;1579  %f = fcmp one float %x, 0.000000e+001580  %neg = fneg float %x1581  %sel = select i1 %f, float %x, float %neg1582  %res = fcmp one float %sel, -0.000000e+001583  ret i1 %res1584}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:%.*]], zeroinitializer1589; CHECK-NEXT:    ret <8 x i1> [[RES]]1590;1591  %f = fcmp ueq <8 x float> %x, zeroinitializer1592  %neg = fneg <8 x float> %x1593  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg1594  %res = fcmp ueq <8 x float> %sel, zeroinitializer1595  ret <8 x i1> %res1596}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:%.*]], zeroinitializer1601; CHECK-NEXT:    ret <8 x i1> [[RES]]1602;1603  %f = fcmp une <8 x float> %x, zeroinitializer1604  %neg = fneg <8 x float> %x1605  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg1606  %res = fcmp une <8 x float> %sel, zeroinitializer1607  ret <8 x i1> %res1608}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:%.*]], zeroinitializer1613; CHECK-NEXT:    ret <8 x i1> [[RES]]1614;1615  %f = fcmp oeq <8 x float> %x, zeroinitializer1616  %neg = fneg <8 x float> %x1617  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg1618  %res = fcmp oeq <8 x float> %sel, zeroinitializer1619  ret <8 x i1> %res1620}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:%.*]], zeroinitializer1625; CHECK-NEXT:    ret <8 x i1> [[RES]]1626;1627  %f = fcmp one <8 x float> %x, zeroinitializer1628  %neg = fneg <8 x float> %x1629  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg1630  %res = fcmp one <8 x float> %sel, zeroinitializer1631  ret <8 x i1> %res1632}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:%.*]], zeroinitializer1637; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1638;1639  %fneg = fneg <2 x float> %x1640  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1641  %icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0>1642  ret <2 x i1> %icmp1643}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:%.*]], zeroinitializer1648; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1649;1650  %fneg = fneg <2 x float> %x1651  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1652  %icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0>1653  ret <2 x i1> %icmp1654}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:%.*]], zeroinitializer1659; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1660;1661  %fneg = fneg <2 x float> %x1662  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1663  %icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0>1664  ret <2 x i1> %icmp1665}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:%.*]], zeroinitializer1670; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1671;1672  %fneg = fneg <2 x float> %x1673  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1674  %icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0>1675  ret <2 x i1> %icmp1676}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:%.*]], zeroinitializer1681; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1682;1683  %fneg = fneg <2 x float> %x1684  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1685  %icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0>1686  ret <2 x i1> %icmp1687}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:%.*]], zeroinitializer1692; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1693;1694  %fneg = fneg <2 x float> %x1695  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1696  %icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0>1697  ret <2 x i1> %icmp1698}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:%.*]], zeroinitializer1703; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1704;1705  %fneg = fneg <2 x float> %x1706  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1707  %icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0>1708  ret <2 x i1> %icmp1709}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:%.*]], zeroinitializer1714; CHECK-NEXT:    ret <2 x i1> [[ICMP]]1715;1716  %fneg = fneg <2 x float> %x1717  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg1718  %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>1719  ret <2 x i1> %icmp1720}1721 1722; negative test - extra use1723 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+001729; CHECK-NEXT:    ret i1 [[CMP]]1730;1731  %fs = fsub nnan float %x, %y1732  call void @use(float %fs)1733  %cmp = fcmp nnan ueq float %fs, 0.000000e+001734  ret i1 %cmp1735}1736 1737; negative test - extra use1738 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+001744; CHECK-NEXT:    ret i1 [[CMP]]1745;1746  %fs = fsub ninf float %x, %y1747  call void @use(float %fs)1748  %cmp = fcmp ninf oeq float %fs, 0.000000e+001749  ret i1 %cmp1750}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+001756; CHECK-NEXT:    ret i1 [[CMP]]1757;1758  %fs = fsub float %x, %y1759  %cmp = fcmp oeq float %fs, 0.000000e+001760  ret i1 %cmp1761}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+001767; CHECK-NEXT:    ret i1 [[CMP]]1768;1769  %fs = fsub float %x, %y1770  %cmp = fcmp oge float %fs, 0.000000e+001771  ret i1 %cmp1772}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+001778; CHECK-NEXT:    ret i1 [[CMP]]1779;1780  %fs = fsub float %x, %y1781  %cmp = fcmp ole float %fs, 0.000000e+001782  ret i1 %cmp1783}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, %y1791  %cmp = fcmp ueq float %fs, 0.000000e+001792  ret i1 %cmp1793}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, %y1801  %cmp = fcmp uge float %fs, 0.000000e+001802  ret i1 %cmp1803}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, %y1811  %cmp = fcmp ule float %fs, 0.000000e+001812  ret i1 %cmp1813}1814 1815define i1 @fcmp_ninf_ule_fsub_const(float %x, float %y) {1816; CHECK-LABEL: @fcmp_ninf_ule_fsub_const(1817; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]1818; CHECK-NEXT:    ret i1 [[CMP]]1819;1820  %fs = fsub float %x, %y1821  %cmp = fcmp ninf ule float %fs, 0.000000e+001822  ret i1 %cmp1823}1824 1825define i1 @fcmp_nnan_ule_fsub_const(float %x, float %y) {1826; CHECK-LABEL: @fcmp_nnan_ule_fsub_const(1827; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[X:%.*]], [[Y:%.*]]1828; CHECK-NEXT:    ret i1 [[CMP]]1829;1830  %fs = fsub float %x, %y1831  %cmp = fcmp nnan ule float %fs, 0.000000e+001832  ret i1 %cmp1833}1834 1835define i1 @fcmp_ule_fsub_ninf_const(float %x, float %y) {1836; CHECK-LABEL: @fcmp_ule_fsub_ninf_const(1837; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ule float [[X:%.*]], [[Y:%.*]]1838; CHECK-NEXT:    ret i1 [[CMP]]1839;1840  %fs = fsub ninf float %x, %y1841  %cmp = fcmp ule float %fs, 0.000000e+001842  ret i1 %cmp1843}1844 1845define i1 @fcmp_ule_fsub_nnan_const(float %x, float %y) {1846; CHECK-LABEL: @fcmp_ule_fsub_nnan_const(1847; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[X:%.*]], [[Y:%.*]]1848; CHECK-NEXT:    ret i1 [[CMP]]1849;1850  %fs = fsub nnan float %x, %y1851  %cmp = fcmp ule float %fs, 0.000000e+001852  ret i1 %cmp1853}1854 1855define i1 @fcmp_ugt_fsub_const(float %x, float %y) {1856; CHECK-LABEL: @fcmp_ugt_fsub_const(1857; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]1858; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[FS]], 0.000000e+001859; CHECK-NEXT:    ret i1 [[CMP]]1860;1861  %fs = fsub float %x, %y1862  %cmp = fcmp ugt float %fs, 0.000000e+001863  ret i1 %cmp1864}1865 1866define i1 @fcmp_ult_fsub_const(float %x, float %y) {1867; CHECK-LABEL: @fcmp_ult_fsub_const(1868; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]1869; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[FS]], 0.000000e+001870; CHECK-NEXT:    ret i1 [[CMP]]1871;1872  %fs = fsub float %x, %y1873  %cmp = fcmp ult float %fs, 0.000000e+001874  ret i1 %cmp1875}1876 1877define i1 @fcmp_une_fsub_const(float %x, float %y) {1878; CHECK-LABEL: @fcmp_une_fsub_const(1879; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]1880; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[FS]], 0.000000e+001881; CHECK-NEXT:    ret i1 [[CMP]]1882;1883  %fs = fsub float %x, %y1884  %cmp = fcmp une float %fs, 0.000000e+001885  ret i1 %cmp1886}1887 1888define <8 x i1> @fcmp_uge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1889; CHECK-LABEL: @fcmp_uge_fsub_const_ninf_vec(1890; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf uge <8 x float> [[X:%.*]], [[Y:%.*]]1891; CHECK-NEXT:    ret <8 x i1> [[CMP]]1892;1893  %fs = fsub ninf <8 x float> %x, %y1894  %cmp = fcmp ninf uge <8 x float> %fs, zeroinitializer1895  ret <8 x i1> %cmp1896}1897 1898define <8 x i1> @fcmp_ule_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1899; CHECK-LABEL: @fcmp_ule_fsub_const_ninf_vec(1900; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ule <8 x float> [[X:%.*]], [[Y:%.*]]1901; CHECK-NEXT:    ret <8 x i1> [[CMP]]1902;1903  %fs = fsub ninf <8 x float> %x, %y1904  %cmp = fcmp ninf ule <8 x float> %fs, zeroinitializer1905  ret <8 x i1> %cmp1906}1907 1908define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1909; CHECK-LABEL: @fcmp_ueq_fsub_const_ninf_vec(1910; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ueq <8 x float> [[X:%.*]], [[Y:%.*]]1911; CHECK-NEXT:    ret <8 x i1> [[CMP]]1912;1913  %fs = fsub ninf <8 x float> %x, %y1914  %cmp = fcmp ninf ueq <8 x float> %fs, zeroinitializer1915  ret <8 x i1> %cmp1916}1917 1918define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1919; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec(1920; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge <8 x float> [[X:%.*]], [[Y:%.*]]1921; CHECK-NEXT:    ret <8 x i1> [[CMP]]1922;1923  %fs = fsub ninf <8 x float> %x, %y1924  %cmp = fcmp ninf oge <8 x float> %fs, zeroinitializer1925  ret <8 x i1> %cmp1926}1927 1928define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1929; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec(1930; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole <8 x float> [[X:%.*]], [[Y:%.*]]1931; CHECK-NEXT:    ret <8 x i1> [[CMP]]1932;1933  %fs = fsub ninf <8 x float> %x, %y1934  %cmp = fcmp ninf ole <8 x float> %fs, zeroinitializer1935  ret <8 x i1> %cmp1936}1937 1938define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1939; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec(1940; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[X:%.*]], [[Y:%.*]]1941; CHECK-NEXT:    ret <8 x i1> [[CMP]]1942;1943  %fs = fsub ninf <8 x float> %x, %y1944  %cmp = fcmp ninf oeq <8 x float> %fs, zeroinitializer1945  ret <8 x i1> %cmp1946}1947 1948define <8 x i1> @fcmp_ogt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1949; CHECK-LABEL: @fcmp_ogt_fsub_const_ninf_vec(1950; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <8 x float> [[X:%.*]], [[Y:%.*]]1951; CHECK-NEXT:    ret <8 x i1> [[CMP]]1952;1953  %fs = fsub ninf <8 x float> %x, %y1954  %cmp = fcmp ninf ogt <8 x float> %fs, zeroinitializer1955  ret <8 x i1> %cmp1956}1957 1958define <8 x i1> @fcmp_olt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1959; CHECK-LABEL: @fcmp_olt_fsub_const_ninf_vec(1960; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <8 x float> [[X:%.*]], [[Y:%.*]]1961; CHECK-NEXT:    ret <8 x i1> [[CMP]]1962;1963  %fs = fsub ninf <8 x float> %x, %y1964  %cmp = fcmp ninf olt <8 x float> %fs, zeroinitializer1965  ret <8 x i1> %cmp1966}1967 1968define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1969; CHECK-LABEL: @fcmp_one_fsub_const_ninf_vec(1970; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf one <8 x float> [[X:%.*]], [[Y:%.*]]1971; CHECK-NEXT:    ret <8 x i1> [[CMP]]1972;1973  %fs = fsub ninf <8 x float> %x, %y1974  %cmp = fcmp ninf one <8 x float> %fs, zeroinitializer1975  ret <8 x i1> %cmp1976}1977 1978define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1979; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec(1980; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[X:%.*]], [[Y:%.*]]1981; CHECK-NEXT:    ret <8 x i1> [[CMP]]1982;1983  %fs = fsub ninf <8 x float> %x, %y1984  %cmp = fcmp ninf ugt <8 x float> %fs, zeroinitializer1985  ret <8 x i1> %cmp1986}1987 1988define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1989; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec(1990; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult <8 x float> [[X:%.*]], [[Y:%.*]]1991; CHECK-NEXT:    ret <8 x i1> [[CMP]]1992;1993  %fs = fsub ninf <8 x float> %x, %y1994  %cmp = fcmp ninf ult <8 x float> %fs, zeroinitializer1995  ret <8 x i1> %cmp1996}1997 1998define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {1999; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec(2000; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une <8 x float> [[X:%.*]], [[Y:%.*]]2001; CHECK-NEXT:    ret <8 x i1> [[CMP]]2002;2003  %fs = fsub ninf <8 x float> %x, %y2004  %cmp = fcmp ninf une <8 x float> %fs, zeroinitializer2005  ret <8 x i1> %cmp2006}2007 2008define <8 x i1> @fcmp_uge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2009; CHECK-LABEL: @fcmp_uge_fsub_const_nnan_vec(2010; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge <8 x float> [[X:%.*]], [[Y:%.*]]2011; CHECK-NEXT:    ret <8 x i1> [[CMP]]2012;2013  %fs = fsub nnan <8 x float> %x, %y2014  %cmp = fcmp nnan uge <8 x float> %fs, zeroinitializer2015  ret <8 x i1> %cmp2016}2017 2018define <8 x i1> @fcmp_ule_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2019; CHECK-LABEL: @fcmp_ule_fsub_const_nnan_vec(2020; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule <8 x float> [[X:%.*]], [[Y:%.*]]2021; CHECK-NEXT:    ret <8 x i1> [[CMP]]2022;2023  %fs = fsub nnan <8 x float> %x, %y2024  %cmp = fcmp nnan ule <8 x float> %fs, zeroinitializer2025  ret <8 x i1> %cmp2026}2027 2028define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2029; CHECK-LABEL: @fcmp_ueq_fsub_const_nnan_vec(2030; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq <8 x float> [[X:%.*]], [[Y:%.*]]2031; CHECK-NEXT:    ret <8 x i1> [[CMP]]2032;2033  %fs = fsub nnan <8 x float> %x, %y2034  %cmp = fcmp nnan ueq <8 x float> %fs, zeroinitializer2035  ret <8 x i1> %cmp2036}2037 2038define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2039; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec(2040; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oge <8 x float> [[X:%.*]], [[Y:%.*]]2041; CHECK-NEXT:    ret <8 x i1> [[CMP]]2042;2043  %fs = fsub nnan <8 x float> %x, %y2044  %cmp = fcmp nnan oge <8 x float> %fs, zeroinitializer2045  ret <8 x i1> %cmp2046}2047 2048define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2049; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec(2050; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <8 x float> [[X:%.*]], [[Y:%.*]]2051; CHECK-NEXT:    ret <8 x i1> [[CMP]]2052;2053  %fs = fsub nnan <8 x float> %x, %y2054  %cmp = fcmp nnan ole <8 x float> %fs, zeroinitializer2055  ret <8 x i1> %cmp2056}2057 2058define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2059; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec(2060; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[X:%.*]], [[Y:%.*]]2061; CHECK-NEXT:    ret <8 x i1> [[CMP]]2062;2063  %fs = fsub nnan <8 x float> %x, %y2064  %cmp = fcmp nnan oeq <8 x float> %fs, zeroinitializer2065  ret <8 x i1> %cmp2066}2067 2068define <8 x i1> @fcmp_ogt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2069; CHECK-LABEL: @fcmp_ogt_fsub_const_nnan_vec(2070; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt <8 x float> [[X:%.*]], [[Y:%.*]]2071; CHECK-NEXT:    ret <8 x i1> [[CMP]]2072;2073  %fs = fsub nnan <8 x float> %x, %y2074  %cmp = fcmp nnan ogt <8 x float> %fs, zeroinitializer2075  ret <8 x i1> %cmp2076}2077 2078define <8 x i1> @fcmp_olt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2079; CHECK-LABEL: @fcmp_olt_fsub_const_nnan_vec(2080; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan olt <8 x float> [[X:%.*]], [[Y:%.*]]2081; CHECK-NEXT:    ret <8 x i1> [[CMP]]2082;2083  %fs = fsub nnan <8 x float> %x, %y2084  %cmp = fcmp nnan olt <8 x float> %fs, zeroinitializer2085  ret <8 x i1> %cmp2086}2087 2088define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2089; CHECK-LABEL: @fcmp_one_fsub_const_nnan_vec(2090; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one <8 x float> [[X:%.*]], [[Y:%.*]]2091; CHECK-NEXT:    ret <8 x i1> [[CMP]]2092;2093  %fs = fsub nnan <8 x float> %x, %y2094  %cmp = fcmp nnan one <8 x float> %fs, zeroinitializer2095  ret <8 x i1> %cmp2096}2097 2098define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2099; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec(2100; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[X:%.*]], [[Y:%.*]]2101; CHECK-NEXT:    ret <8 x i1> [[CMP]]2102;2103  %fs = fsub nnan <8 x float> %x, %y2104  %cmp = fcmp nnan ugt <8 x float> %fs, zeroinitializer2105  ret <8 x i1> %cmp2106}2107 2108define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2109; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec(2110; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ult <8 x float> [[X:%.*]], [[Y:%.*]]2111; CHECK-NEXT:    ret <8 x i1> [[CMP]]2112;2113  %fs = fsub nnan <8 x float> %x, %y2114  %cmp = fcmp nnan ult <8 x float> %fs, zeroinitializer2115  ret <8 x i1> %cmp2116}2117 2118define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {2119; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec(2120; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan une <8 x float> [[X:%.*]], [[Y:%.*]]2121; CHECK-NEXT:    ret <8 x i1> [[CMP]]2122;2123  %fs = fsub nnan <8 x float> %x, %y2124  %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer2125  ret <8 x i1> %cmp2126}2127 2128define <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" {2129; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero(2130; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]2131; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer2132; CHECK-NEXT:    ret <8 x i1> [[CMP]]2133;2134  %fs = fsub <8 x float> %x, %y2135  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer2136  ret <8 x i1> %cmp2137}2138 2139define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="dynamic,dynamic" {2140; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_dynamic(2141; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]2142; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer2143; CHECK-NEXT:    ret <8 x i1> [[CMP]]2144;2145  %fs = fsub <8 x float> %x, %y2146  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer2147  ret <8 x i1> %cmp2148}2149 2150define <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" {2151; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(2152; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]2153; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer2154; CHECK-NEXT:    ret <8 x i1> [[CMP]]2155;2156  %fs = fsub <8 x float> %x, %y2157  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer2158  ret <8 x i1> %cmp2159}2160 2161define i1 @fcmp_sqrt_zero_olt(half %x) {2162; CHECK-LABEL: @fcmp_sqrt_zero_olt(2163; CHECK-NEXT:    ret i1 false2164;2165  %sqrt = call half @llvm.sqrt.f16(half %x)2166  %cmp = fcmp olt half %sqrt, 0.02167  ret i1 %cmp2168}2169 2170define i1 @fcmp_sqrt_zero_ult(half %x) {2171; CHECK-LABEL: @fcmp_sqrt_zero_ult(2172; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH00002173; CHECK-NEXT:    ret i1 [[CMP]]2174;2175  %sqrt = call half @llvm.sqrt.f16(half %x)2176  %cmp = fcmp ult half %sqrt, 0.02177  ret i1 %cmp2178}2179 2180define i1 @fcmp_sqrt_zero_ult_fmf(half %x) {2181; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf(2182; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult half [[X:%.*]], 0xH00002183; CHECK-NEXT:    ret i1 [[CMP]]2184;2185  %sqrt = call half @llvm.sqrt.f16(half %x)2186  %cmp = fcmp ninf nsz ult half %sqrt, 0.02187  ret i1 %cmp2188}2189 2190define i1 @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(half %x) {2191; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(2192; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf nsz ult half [[X:%.*]], 0xH00002193; CHECK-NEXT:    ret i1 [[CMP]]2194;2195  %sqrt = call ninf half @llvm.sqrt.f16(half %x)2196  %cmp = fcmp ninf nsz ult half %sqrt, 0.02197  ret i1 %cmp2198}2199 2200define i1 @fcmp_sqrt_zero_ult_nzero(half %x) {2201; CHECK-LABEL: @fcmp_sqrt_zero_ult_nzero(2202; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH00002203; CHECK-NEXT:    ret i1 [[CMP]]2204;2205  %sqrt = call half @llvm.sqrt.f16(half %x)2206  %cmp = fcmp ult half %sqrt, -0.02207  ret i1 %cmp2208}2209 2210define <2 x i1> @fcmp_sqrt_zero_ult_vec(<2 x half> %x) {2211; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec(2212; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer2213; CHECK-NEXT:    ret <2 x i1> [[CMP]]2214;2215  %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)2216  %cmp = fcmp ult <2 x half> %sqrt, zeroinitializer2217  ret <2 x i1> %cmp2218}2219 2220define <2 x i1> @fcmp_sqrt_zero_ult_vec_mixed_zero(<2 x half> %x) {2221; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec_mixed_zero(2222; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer2223; CHECK-NEXT:    ret <2 x i1> [[CMP]]2224;2225  %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)2226  %cmp = fcmp ult <2 x half> %sqrt, <half 0.0, half -0.0>2227  ret <2 x i1> %cmp2228}2229 2230define i1 @fcmp_sqrt_zero_ole(half %x) {2231; CHECK-LABEL: @fcmp_sqrt_zero_ole(2232; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH00002233; CHECK-NEXT:    ret i1 [[CMP]]2234;2235  %sqrt = call half @llvm.sqrt.f16(half %x)2236  %cmp = fcmp ole half %sqrt, 0.02237  ret i1 %cmp2238}2239 2240define i1 @fcmp_sqrt_zero_ule(half %x) {2241; CHECK-LABEL: @fcmp_sqrt_zero_ule(2242; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH00002243; CHECK-NEXT:    ret i1 [[CMP]]2244;2245  %sqrt = call half @llvm.sqrt.f16(half %x)2246  %cmp = fcmp ule half %sqrt, 0.02247  ret i1 %cmp2248}2249 2250define i1 @fcmp_sqrt_zero_ogt(half %x) {2251; CHECK-LABEL: @fcmp_sqrt_zero_ogt(2252; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH00002253; CHECK-NEXT:    ret i1 [[CMP]]2254;2255  %sqrt = call half @llvm.sqrt.f16(half %x)2256  %cmp = fcmp ogt half %sqrt, 0.02257  ret i1 %cmp2258}2259 2260define i1 @fcmp_sqrt_zero_ugt(half %x) {2261; CHECK-LABEL: @fcmp_sqrt_zero_ugt(2262; CHECK-NEXT:    [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH00002263; CHECK-NEXT:    ret i1 [[CMP]]2264;2265  %sqrt = call half @llvm.sqrt.f16(half %x)2266  %cmp = fcmp ugt half %sqrt, 0.02267  ret i1 %cmp2268}2269 2270define i1 @fcmp_sqrt_zero_oge(half %x) {2271; CHECK-LABEL: @fcmp_sqrt_zero_oge(2272; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH00002273; CHECK-NEXT:    ret i1 [[CMP]]2274;2275  %sqrt = call half @llvm.sqrt.f16(half %x)2276  %cmp = fcmp oge half %sqrt, 0.02277  ret i1 %cmp2278}2279 2280define i1 @fcmp_sqrt_zero_uge(half %x) {2281; CHECK-LABEL: @fcmp_sqrt_zero_uge(2282; CHECK-NEXT:    ret i1 true2283;2284  %sqrt = call half @llvm.sqrt.f16(half %x)2285  %cmp = fcmp uge half %sqrt, 0.02286  ret i1 %cmp2287}2288 2289define i1 @fcmp_sqrt_zero_oeq(half %x) {2290; CHECK-LABEL: @fcmp_sqrt_zero_oeq(2291; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH00002292; CHECK-NEXT:    ret i1 [[CMP]]2293;2294  %sqrt = call half @llvm.sqrt.f16(half %x)2295  %cmp = fcmp oeq half %sqrt, 0.02296  ret i1 %cmp2297}2298 2299define i1 @fcmp_sqrt_zero_ueq(half %x) {2300; CHECK-LABEL: @fcmp_sqrt_zero_ueq(2301; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH00002302; CHECK-NEXT:    ret i1 [[CMP]]2303;2304  %sqrt = call half @llvm.sqrt.f16(half %x)2305  %cmp = fcmp ueq half %sqrt, 0.02306  ret i1 %cmp2307}2308 2309define i1 @fcmp_sqrt_zero_one(half %x) {2310; CHECK-LABEL: @fcmp_sqrt_zero_one(2311; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH00002312; CHECK-NEXT:    ret i1 [[CMP]]2313;2314  %sqrt = call half @llvm.sqrt.f16(half %x)2315  %cmp = fcmp one half %sqrt, 0.02316  ret i1 %cmp2317}2318 2319define i1 @fcmp_sqrt_zero_une(half %x) {2320; CHECK-LABEL: @fcmp_sqrt_zero_une(2321; CHECK-NEXT:    [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH00002322; CHECK-NEXT:    ret i1 [[CMP]]2323;2324  %sqrt = call half @llvm.sqrt.f16(half %x)2325  %cmp = fcmp une half %sqrt, 0.02326  ret i1 %cmp2327}2328 2329define i1 @fcmp_sqrt_zero_ord(half %x) {2330; CHECK-LABEL: @fcmp_sqrt_zero_ord(2331; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH00002332; CHECK-NEXT:    ret i1 [[CMP]]2333;2334  %sqrt = call half @llvm.sqrt.f16(half %x)2335  %cmp = fcmp ord half %sqrt, 0.02336  ret i1 %cmp2337}2338 2339define i1 @fcmp_sqrt_zero_uno(half %x) {2340; CHECK-LABEL: @fcmp_sqrt_zero_uno(2341; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH00002342; CHECK-NEXT:    ret i1 [[CMP]]2343;2344  %sqrt = call half @llvm.sqrt.f16(half %x)2345  %cmp = fcmp uno half %sqrt, 0.02346  ret i1 %cmp2347}2348 2349; Make sure that ninf is cleared.2350define i1 @fcmp_sqrt_zero_uno_fmf(half %x) {2351; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf(2352; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH00002353; CHECK-NEXT:    ret i1 [[CMP]]2354;2355  %sqrt = call half @llvm.sqrt.f16(half %x)2356  %cmp = fcmp ninf uno half %sqrt, 0.02357  ret i1 %cmp2358}2359 2360define i1 @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(half %x) {2361; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(2362; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult half [[X:%.*]], 0xH00002363; CHECK-NEXT:    ret i1 [[CMP]]2364;2365  %sqrt = call ninf half @llvm.sqrt.f16(half %x)2366  %cmp = fcmp ninf uno half %sqrt, 0.02367  ret i1 %cmp2368}2369 2370; negative tests2371 2372define i1 @fcmp_sqrt_zero_ult_var(half %x, half %y) {2373; CHECK-LABEL: @fcmp_sqrt_zero_ult_var(2374; CHECK-NEXT:    [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])2375; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[SQRT]], [[Y:%.*]]2376; CHECK-NEXT:    ret i1 [[CMP]]2377;2378  %sqrt = call half @llvm.sqrt.f16(half %x)2379  %cmp = fcmp ult half %sqrt, %y2380  ret i1 %cmp2381}2382 2383define i1 @fcmp_sqrt_zero_ult_nonzero(half %x) {2384; CHECK-LABEL: @fcmp_sqrt_zero_ult_nonzero(2385; CHECK-NEXT:    [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])2386; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[SQRT]], 0xH3C002387; CHECK-NEXT:    ret i1 [[CMP]]2388;2389  %sqrt = call half @llvm.sqrt.f16(half %x)2390  %cmp = fcmp ult half %sqrt, 1.000000e+002391  ret i1 %cmp2392}2393