1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define i1 @fcmp_ord_and_uno(half %x, half %y) { 5; CHECK-LABEL: @fcmp_ord_and_uno( 6; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 7; CHECK-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], [[Y:%.*]] 8; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UNO]] 9; CHECK-NEXT: ret i1 [[AND]] 10; 11 %ord = fcmp ord half %x, 0.0 12 %uno = fcmp uno half %x, %y 13 %and = and i1 %ord, %uno 14 ret i1 %and 15} 16 17define i1 @fcmp_ord_and_ueq(half %x, half %y) { 18; CHECK-LABEL: @fcmp_ord_and_ueq( 19; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 20; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] 21; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 22; CHECK-NEXT: ret i1 [[AND]] 23; 24 %ord = fcmp ord half %x, 0.0 25 %ueq = fcmp ueq half %x, %y 26 %and = and i1 %ord, %ueq 27 ret i1 %and 28} 29 30define i1 @fcmp_ord_and_ugt(half %x, half %y) { 31; CHECK-LABEL: @fcmp_ord_and_ugt( 32; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 33; CHECK-NEXT: [[UGT:%.*]] = fcmp ugt half [[X]], [[Y:%.*]] 34; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UGT]] 35; CHECK-NEXT: ret i1 [[AND]] 36; 37 %ord = fcmp ord half %x, 0.0 38 %ugt = fcmp ugt half %x, %y 39 %and = and i1 %ord, %ugt 40 ret i1 %and 41} 42 43define i1 @fcmp_ord_and_uge(half %x, half %y) { 44; CHECK-LABEL: @fcmp_ord_and_uge( 45; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 46; CHECK-NEXT: [[UGE:%.*]] = fcmp uge half [[X]], [[Y:%.*]] 47; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UGE]] 48; CHECK-NEXT: ret i1 [[AND]] 49; 50 %ord = fcmp ord half %x, 0.0 51 %uge = fcmp uge half %x, %y 52 %and = and i1 %ord, %uge 53 ret i1 %and 54} 55 56define i1 @fcmp_ord_and_ult(half %x, half %y) { 57; CHECK-LABEL: @fcmp_ord_and_ult( 58; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 59; CHECK-NEXT: [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]] 60; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULT]] 61; CHECK-NEXT: ret i1 [[AND]] 62; 63 %ord = fcmp ord half %x, 0.0 64 %ult = fcmp ult half %x, %y 65 %and = and i1 %ord, %ult 66 ret i1 %and 67} 68 69define i1 @fcmp_ord_and_ule(half %x, half %y) { 70; CHECK-LABEL: @fcmp_ord_and_ule( 71; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 72; CHECK-NEXT: [[ULE:%.*]] = fcmp ule half [[X]], [[Y:%.*]] 73; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULE]] 74; CHECK-NEXT: ret i1 [[AND]] 75; 76 %ord = fcmp ord half %x, 0.0 77 %ule = fcmp ule half %x, %y 78 %and = and i1 %ord, %ule 79 ret i1 %and 80} 81 82define i1 @fcmp_ord_and_une(half %x, half %y) { 83; CHECK-LABEL: @fcmp_ord_and_une( 84; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 85; CHECK-NEXT: [[UNE:%.*]] = fcmp une half [[X]], [[Y:%.*]] 86; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UNE]] 87; CHECK-NEXT: ret i1 [[AND]] 88; 89 %ord = fcmp ord half %x, 0.0 90 %une = fcmp une half %x, %y 91 %and = and i1 %ord, %une 92 ret i1 %and 93} 94 95define i1 @fcmp_ord_and_true(half %x, half %y) { 96; CHECK-LABEL: @fcmp_ord_and_true( 97; CHECK-NEXT: [[UNE:%.*]] = fcmp une half [[X:%.*]], [[Y:%.*]] 98; CHECK-NEXT: ret i1 [[UNE]] 99; 100 %ord = fcmp true half %x, 0.0 101 %une = fcmp une half %x, %y 102 %and = and i1 %ord, %une 103 ret i1 %and 104} 105 106define <2 x i1> @fcmp_ord_and_ueq_vector(<2 x half> %x, <2 x half> %y) { 107; CHECK-LABEL: @fcmp_ord_and_ueq_vector( 108; CHECK-NEXT: [[ORD:%.*]] = fcmp ord <2 x half> [[X:%.*]], zeroinitializer 109; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq <2 x half> [[X]], [[Y:%.*]] 110; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]] 111; CHECK-NEXT: ret <2 x i1> [[AND]] 112; 113 %ord = fcmp ord <2 x half> %x, zeroinitializer 114 %ueq = fcmp ueq <2 x half> %x, %y 115 %and = and <2 x i1> %ord, %ueq 116 ret <2 x i1> %and 117} 118 119; Negative test 120define i1 @fcmp_ord_and_ueq_different_value0(half %x, half %y, half %z) { 121; CHECK-LABEL: @fcmp_ord_and_ueq_different_value0( 122; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 123; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Z:%.*]], [[Y:%.*]] 124; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 125; CHECK-NEXT: ret i1 [[AND]] 126; 127 %ord = fcmp ord half %x, 0.0 128 %ueq = fcmp ueq half %z, %y 129 %and = and i1 %ord, %ueq 130 ret i1 %and 131} 132 133; Negative test 134define i1 @fcmp_ord_and_ueq_different_value1(half %x, half %y, half %z) { 135; CHECK-LABEL: @fcmp_ord_and_ueq_different_value1( 136; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 137; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[Z:%.*]] 138; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 139; CHECK-NEXT: ret i1 [[AND]] 140; 141 %ord = fcmp ord half %x, 0.0 142 %ueq = fcmp ueq half %y, %z 143 %and = and i1 %ord, %ueq 144 ret i1 %and 145} 146 147declare half @foo() 148 149define i1 @fcmp_ord_and_ueq_commute0() { 150; CHECK-LABEL: @fcmp_ord_and_ueq_commute0( 151; CHECK-NEXT: [[X:%.*]] = call half @foo() 152; CHECK-NEXT: [[Y:%.*]] = call half @foo() 153; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 154; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]] 155; CHECK-NEXT: [[AND:%.*]] = and i1 [[UEQ]], [[ORD]] 156; CHECK-NEXT: ret i1 [[AND]] 157; 158 %x = call half @foo() 159 %y = call half @foo() 160 %ord = fcmp ord half %x, 0.0 161 %ueq = fcmp ueq half %x, %y 162 %and = and i1 %ueq, %ord 163 ret i1 %and 164} 165 166define i1 @fcmp_ord_and_ueq_commute1() { 167; CHECK-LABEL: @fcmp_ord_and_ueq_commute1( 168; CHECK-NEXT: [[X:%.*]] = call half @foo() 169; CHECK-NEXT: [[Y:%.*]] = call half @foo() 170; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 171; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]] 172; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 173; CHECK-NEXT: ret i1 [[AND]] 174; 175 %x = call half @foo() 176 %y = call half @foo() 177 %ord = fcmp ord half %x, 0.0 178 %ueq = fcmp ueq half %x, %y 179 %and = and i1 %ord, %ueq 180 ret i1 %and 181} 182 183define i1 @fcmp_oeq_x_x_and_ult(half %x, half %y) { 184; CHECK-LABEL: @fcmp_oeq_x_x_and_ult( 185; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 186; CHECK-NEXT: [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]] 187; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[ULT]] 188; CHECK-NEXT: ret i1 [[AND]] 189; 190 %ord = fcmp oeq half %x, %x ; noncanonical ordered 191 %ult = fcmp ult half %x, %y 192 %and = and i1 %ord, %ult 193 ret i1 %and 194} 195 196define i1 @fcmp_ord_and_ueq_preserve_flags(half %x, half %y) { 197; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_flags( 198; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 199; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] 200; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 201; CHECK-NEXT: ret i1 [[AND]] 202; 203 %ord = fcmp nsz ord half %x, 0.0 204 %ueq = fcmp nsz ueq half %x, %y 205 %and = and i1 %ord, %ueq 206 ret i1 %and 207} 208 209define i1 @fcmp_ord_and_ueq_preserve_subset_flags0(half %x, half %y) { 210; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags0( 211; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 212; CHECK-NEXT: [[UEQ:%.*]] = fcmp ninf nsz ueq half [[X]], [[Y:%.*]] 213; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 214; CHECK-NEXT: ret i1 [[AND]] 215; 216 %ord = fcmp nsz ord half %x, 0.0 217 %ueq = fcmp ninf nsz ueq half %x, %y 218 %and = and i1 %ord, %ueq 219 ret i1 %and 220} 221 222define i1 @fcmp_ord_and_ueq_preserve_subset_flags1(half %x, half %y) { 223; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags1( 224; CHECK-NEXT: [[ORD:%.*]] = fcmp ninf nsz ord half [[X:%.*]], 0xH0000 225; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] 226; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 227; CHECK-NEXT: ret i1 [[AND]] 228; 229 %ord = fcmp ninf nsz ord half %x, 0.0 230 %ueq = fcmp nsz ueq half %x, %y 231 %and = and i1 %ord, %ueq 232 ret i1 %and 233} 234 235define i1 @fcmp_ord_and_ueq_flags_lhs(half %x, half %y) { 236; CHECK-LABEL: @fcmp_ord_and_ueq_flags_lhs( 237; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000 238; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] 239; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 240; CHECK-NEXT: ret i1 [[AND]] 241; 242 %ord = fcmp nsz ord half %x, 0.0 243 %ueq = fcmp ueq half %x, %y 244 %and = and i1 %ord, %ueq 245 ret i1 %and 246} 247 248define i1 @fcmp_ord_and_ueq_flags_rhs(half %x, half %y) { 249; CHECK-LABEL: @fcmp_ord_and_ueq_flags_rhs( 250; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 251; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]] 252; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 253; CHECK-NEXT: ret i1 [[AND]] 254; 255 %ord = fcmp ord half %x, 0.0 256 %ueq = fcmp nsz ueq half %x, %y 257 %and = and i1 %ord, %ueq 258 ret i1 %and 259} 260 261; Can ignore fabs and fneg 262define i1 @fcmp_ord_and_fabs_ueq(half %x, half %y) { 263; CHECK-LABEL: @fcmp_ord_and_fabs_ueq( 264; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 265; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 266; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]] 267; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 268; CHECK-NEXT: ret i1 [[AND]] 269; 270 %fabs.x = call half @llvm.fabs.f16(half %x) 271 %ord = fcmp ord half %x, 0.0 272 %ueq = fcmp ueq half %fabs.x, %y 273 %and = and i1 %ord, %ueq 274 ret i1 %and 275} 276 277define i1 @fcmp_ord_fabs_and_ueq(half %x, half %y) { 278; CHECK-LABEL: @fcmp_ord_fabs_and_ueq( 279; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 280; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] 281; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 282; CHECK-NEXT: ret i1 [[AND]] 283; 284 %fabs.x = call half @llvm.fabs.f16(half %x) 285 %ord = fcmp ord half %fabs.x, 0.0 286 %ueq = fcmp ueq half %x, %y 287 %and = and i1 %ord, %ueq 288 ret i1 %and 289} 290 291define i1 @fcmp_ord_and_fabs_ueq_commute0() { 292; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute0( 293; CHECK-NEXT: [[X:%.*]] = call half @foo() 294; CHECK-NEXT: [[Y:%.*]] = call half @foo() 295; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]]) 296; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 297; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]] 298; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 299; CHECK-NEXT: ret i1 [[AND]] 300; 301 %x = call half @foo() 302 %y = call half @foo() 303 %fabs.x = call half @llvm.fabs.f16(half %x) 304 %ord = fcmp ord half %x, 0.0 305 %ueq = fcmp ueq half %y, %fabs.x 306 %and = and i1 %ord, %ueq 307 ret i1 %and 308} 309 310define i1 @fcmp_ord_and_fabs_ueq_commute1() { 311; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute1( 312; CHECK-NEXT: [[X:%.*]] = call half @foo() 313; CHECK-NEXT: [[Y:%.*]] = call half @foo() 314; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]]) 315; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 316; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]] 317; CHECK-NEXT: [[AND:%.*]] = and i1 [[UEQ]], [[ORD]] 318; CHECK-NEXT: ret i1 [[AND]] 319; 320 %x = call half @foo() 321 %y = call half @foo() 322 %fabs.x = call half @llvm.fabs.f16(half %x) 323 %ord = fcmp ord half %x, 0.0 324 %ueq = fcmp ueq half %y, %fabs.x 325 %and = and i1 %ueq, %ord 326 ret i1 %and 327} 328 329define <2 x i1> @fcmp_ord_and_fabs_ueq_vector(<2 x half> %x, <2 x half> %y) { 330; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_vector( 331; CHECK-NEXT: [[FABS_X:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) 332; CHECK-NEXT: [[ORD:%.*]] = fcmp ord <2 x half> [[X]], zeroinitializer 333; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq <2 x half> [[FABS_X]], [[Y:%.*]] 334; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]] 335; CHECK-NEXT: ret <2 x i1> [[AND]] 336; 337 %fabs.x = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 338 %ord = fcmp ord <2 x half> %x, zeroinitializer 339 %ueq = fcmp ueq <2 x half> %fabs.x, %y 340 %and = and <2 x i1> %ord, %ueq 341 ret <2 x i1> %and 342} 343 344define i1 @fcmp_ord_fabs_and_fabs_ueq(half %x, half %y) { 345; CHECK-LABEL: @fcmp_ord_fabs_and_fabs_ueq( 346; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 347; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 348; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]] 349; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 350; CHECK-NEXT: ret i1 [[AND]] 351; 352 %fabs.x = call half @llvm.fabs.f16(half %x) 353 %ord = fcmp ord half %fabs.x, 0.0 354 %ueq = fcmp ueq half %fabs.x, %y 355 %and = and i1 %ord, %ueq 356 ret i1 %and 357} 358 359define i1 @fcmp_ord_and_fneg_ueq(half %x, half %y) { 360; CHECK-LABEL: @fcmp_ord_and_fneg_ueq( 361; CHECK-NEXT: [[FNEG_X:%.*]] = fneg half [[X:%.*]] 362; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 363; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_X]] 364; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 365; CHECK-NEXT: ret i1 [[AND]] 366; 367 %fneg.x = fneg half %x 368 %ord = fcmp ord half %x, 0.0 369 %ueq = fcmp ueq half %fneg.x, %y 370 %and = and i1 %ord, %ueq 371 ret i1 %and 372} 373 374define i1 @fcmp_ord_fneg_and_ueq(half %x, half %y) { 375; CHECK-LABEL: @fcmp_ord_fneg_and_ueq( 376; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 377; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] 378; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 379; CHECK-NEXT: ret i1 [[AND]] 380; 381 %fneg.x = fneg half %x 382 %ord = fcmp ord half %fneg.x, 0.0 383 %ueq = fcmp ueq half %x, %y 384 %and = and i1 %ord, %ueq 385 ret i1 %and 386} 387 388define i1 @fcmp_ord_fneg_and_fneg_ueq(half %x, half %y) { 389; CHECK-LABEL: @fcmp_ord_fneg_and_fneg_ueq( 390; CHECK-NEXT: [[FNEG_X:%.*]] = fneg half [[X:%.*]] 391; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 392; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_X]] 393; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 394; CHECK-NEXT: ret i1 [[AND]] 395; 396 %fneg.x = fneg half %x 397 %ord = fcmp ord half %fneg.x, 0.0 398 %ueq = fcmp ueq half %fneg.x, %y 399 %and = and i1 %ord, %ueq 400 ret i1 %and 401} 402 403define i1 @fcmp_ord_and_fneg_fabs_ueq(half %x, half %y) { 404; CHECK-LABEL: @fcmp_ord_and_fneg_fabs_ueq( 405; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 406; CHECK-NEXT: [[FNEG_FABS_X:%.*]] = fneg half [[FABS_X]] 407; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 408; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[FNEG_FABS_X]] 409; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 410; CHECK-NEXT: ret i1 [[AND]] 411; 412 %fabs.x = call half @llvm.fabs.f16(half %x) 413 %fneg.fabs.x = fneg half %fabs.x 414 %ord = fcmp ord half %x, 0.0 415 %ueq = fcmp ueq half %fneg.fabs.x, %y 416 %and = and i1 %ord, %ueq 417 ret i1 %and 418} 419 420define i1 @fcmp_ord_and_copysign_ueq(half %x, half %y, half %z) { 421; CHECK-LABEL: @fcmp_ord_and_copysign_ueq( 422; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) 423; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 424; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]] 425; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 426; CHECK-NEXT: ret i1 [[AND]] 427; 428 %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) 429 %ord = fcmp ord half %x, 0.0 430 %ueq = fcmp ueq half %copysign.x.y, %y 431 %and = and i1 %ord, %ueq 432 ret i1 %and 433} 434 435define i1 @fcmp_copysign_ord_and_ueq(half %x, half %y, half %z) { 436; CHECK-LABEL: @fcmp_copysign_ord_and_ueq( 437; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) 438; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[COPYSIGN_X_Y]], 0xH0000 439; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]] 440; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 441; CHECK-NEXT: ret i1 [[AND]] 442; 443 %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) 444 %ord = fcmp ord half %copysign.x.y, 0.0 445 %ueq = fcmp ueq half %x, %y 446 %and = and i1 %ord, %ueq 447 ret i1 %and 448} 449 450define i1 @fcmp_ord_and_copysign_ueq_commute(half %x, half %y, half %z) { 451; CHECK-LABEL: @fcmp_ord_and_copysign_ueq_commute( 452; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) 453; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 454; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[COPYSIGN_X_Y]] 455; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 456; CHECK-NEXT: ret i1 [[AND]] 457; 458 %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) 459 %ord = fcmp ord half %x, 0.0 460 %ueq = fcmp ueq half %y, %copysign.x.y 461 %and = and i1 %ord, %ueq 462 ret i1 %and 463} 464 465define i1 @fcmp_ord_and_copysign_fneg_ueq(half %x, half %y, half %z) { 466; CHECK-LABEL: @fcmp_ord_and_copysign_fneg_ueq( 467; CHECK-NEXT: [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]]) 468; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 469; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]] 470; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 471; CHECK-NEXT: ret i1 [[AND]] 472; 473 %x.fneg = fneg half %x 474 %copysign.x.y = call half @llvm.copysign.f16(half %x.fneg, half %z) 475 %ord = fcmp ord half %x, 0.0 476 %ueq = fcmp ueq half %copysign.x.y, %y 477 %and = and i1 %ord, %ueq 478 ret i1 %and 479} 480 481define i1 @fcmp_ord_and_fneg_copysign_ueq(half %x, half %y, half %z) { 482; CHECK-LABEL: @fcmp_ord_and_fneg_copysign_ueq( 483; CHECK-NEXT: [[TMP1:%.*]] = fneg half [[Z:%.*]] 484; CHECK-NEXT: [[FNEG_COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[TMP1]]) 485; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 486; CHECK-NEXT: [[UEQ:%.*]] = fcmp ueq half [[FNEG_COPYSIGN]], [[Y:%.*]] 487; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]] 488; CHECK-NEXT: ret i1 [[AND]] 489; 490 %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z) 491 %fneg.copysign = fneg half %copysign.x.y 492 %ord = fcmp ord half %x, 0.0 493 %ueq = fcmp ueq half %fneg.copysign, %y 494 %and = and i1 %ord, %ueq 495 ret i1 %and 496} 497 498 499declare half @llvm.fabs.f16(half) 500declare <2 x half> @llvm.fabs.v2f16(<2 x half>) 501declare half @llvm.copysign.f16(half, half) 502declare <2 x half> @llvm.copysign.v2f16(<2 x half>, <2 x half>) 503