1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4; Test and/or of fcmps that could be folded to llvm.is.fpclass 5 6; -------------------------------------------------------------------- 7; Base pattern, !isfinite(x) || x == 0.0 8; -------------------------------------------------------------------- 9 10; Base pattern !isfinite(x) || x == 0.0 11define i1 @not_isfinite_or_zero_f16(half %x) { 12; CHECK-LABEL: @not_isfinite_or_zero_f16( 13; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615) 14; CHECK-NEXT: ret i1 [[CLASS]] 15; 16 %fabs = call half @llvm.fabs.f16(half %x) 17 %cmpinf = fcmp ueq half %fabs, 0xH7C00 18 %cmpzero = fcmp oeq half %x, 0xH0000 19 %class = or i1 %cmpzero, %cmpinf 20 ret i1 %class 21} 22 23; Base pattern x == 0.0 || !isfinite(x) 24define i1 @not_isfinite_or_zero_f16_commute_or(half %x) { 25; CHECK-LABEL: @not_isfinite_or_zero_f16_commute_or( 26; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615) 27; CHECK-NEXT: ret i1 [[CLASS]] 28; 29 %fabs = call half @llvm.fabs.f16(half %x) 30 %cmpinf = fcmp ueq half %fabs, 0xH7C00 31 %cmpzero = fcmp oeq half %x, 0xH0000 32 %class = or i1 %cmpinf, %cmpzero 33 ret i1 %class 34} 35 36; Base pattern !isfinite(x) || x == -0.0 37define i1 @not_isfinite_or_zero_f16_negzero(half %x) { 38; CHECK-LABEL: @not_isfinite_or_zero_f16_negzero( 39; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615) 40; CHECK-NEXT: ret i1 [[CLASS]] 41; 42 %fabs = call half @llvm.fabs.f16(half %x) 43 %cmpinf = fcmp ueq half %fabs, 0xH7C00 44 %cmpzero = fcmp oeq half %x, -0.0 45 %class = or i1 %cmpzero, %cmpinf 46 ret i1 %class 47} 48 49define i1 @not_isfinite_or_fabs_oeq_zero_f16(half %x) { 50; CHECK-LABEL: @not_isfinite_or_fabs_oeq_zero_f16( 51; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615) 52; CHECK-NEXT: ret i1 [[CLASS]] 53; 54 %fabs = call half @llvm.fabs.f16(half %x) 55 %cmpinf = fcmp ueq half %fabs, 0xH7C00 56 %cmpzero = fcmp oeq half %fabs, 0xH0000 57 %class = or i1 %cmpzero, %cmpinf 58 ret i1 %class 59} 60 61; Base pattern !isfinite(x) || x == 0.0 62define <2 x i1> @not_isfinite_or_zero_v2f16(<2 x half> %x) { 63; CHECK-LABEL: @not_isfinite_or_zero_v2f16( 64; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615) 65; CHECK-NEXT: ret <2 x i1> [[CLASS]] 66; 67 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 68 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 69 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer 70 %class = or <2 x i1> %cmpzero, %cmpinf 71 ret <2 x i1> %class 72} 73 74; Base pattern !isfinite(x) || x == <0.0, -0.0> 75define <2 x i1> @not_isfinite_or_zero_v2f16_pos0_neg0_vec(<2 x half> %x) { 76; CHECK-LABEL: @not_isfinite_or_zero_v2f16_pos0_neg0_vec( 77; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615) 78; CHECK-NEXT: ret <2 x i1> [[CLASS]] 79; 80 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 81 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 82 %cmpzero = fcmp oeq <2 x half> %x, <half 0.0, half -0.0> 83 %class = or <2 x i1> %cmpzero, %cmpinf 84 ret <2 x i1> %class 85} 86 87; Base pattern x == 0.0 || !isfinite(x) 88define <2 x i1> @not_isfinite_or_zero_v2f16_commute_or(<2 x half> %x) { 89; CHECK-LABEL: @not_isfinite_or_zero_v2f16_commute_or( 90; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615) 91; CHECK-NEXT: ret <2 x i1> [[CLASS]] 92; 93 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 94 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 95 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer 96 %class = or <2 x i1> %cmpinf, %cmpzero 97 ret <2 x i1> %class 98} 99 100; Positive test 101define i1 @oeq_isinf_or_oeq_zero(half %x) { 102; CHECK-LABEL: @oeq_isinf_or_oeq_zero( 103; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612) 104; CHECK-NEXT: ret i1 [[CLASS]] 105; 106 %fabs = call half @llvm.fabs.f16(half %x) 107 %cmpinf = fcmp oeq half %fabs, 0xH7C00 108 %cmpzero = fcmp oeq half %x, 0xH0000 109 %class = or i1 %cmpzero, %cmpinf 110 ret i1 %class 111} 112 113; Missing fabs for infinity check 114define i1 @ueq_inf_or_oeq_zero(half %x) { 115; CHECK-LABEL: @ueq_inf_or_oeq_zero( 116; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611) 117; CHECK-NEXT: ret i1 [[CLASS]] 118; 119 %cmpinf = fcmp ueq half %x, 0xH7C00 120 %cmpzero = fcmp oeq half %x, 0xH0000 121 %class = or i1 %cmpzero, %cmpinf 122 ret i1 %class 123} 124 125; Extra fabs. 126define i1 @oeq_isinf_or_fabs_oeq_zero(half %x) { 127; CHECK-LABEL: @oeq_isinf_or_fabs_oeq_zero( 128; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612) 129; CHECK-NEXT: ret i1 [[CLASS]] 130; 131 %fabs = call half @llvm.fabs.f16(half %x) 132 %cmpinf = fcmp oeq half %fabs, 0xH7C00 133 %cmpzero = fcmp oeq half %fabs, 0xH0000 134 %class = or i1 %cmpzero, %cmpinf 135 ret i1 %class 136} 137 138; Positive test 139define i1 @ueq_0_or_oeq_inf(half %x) { 140; CHECK-LABEL: @ueq_0_or_oeq_inf( 141; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611) 142; CHECK-NEXT: ret i1 [[CLASS]] 143; 144 %fabs = call half @llvm.fabs.f16(half %x) 145 %cmpinf = fcmp ueq half %fabs, 0xH0000 146 %cmpzero = fcmp oeq half %x, 0xH7C00 147 %class = or i1 %cmpzero, %cmpinf 148 ret i1 %class 149} 150 151; Positive test 152define i1 @not_isfinite_or_zero_f16_not_inf(half %x) { 153; CHECK-LABEL: @not_isfinite_or_zero_f16_not_inf( 154; CHECK-NEXT: ret i1 true 155; 156 %fabs = call half @llvm.fabs.f16(half %x) 157 %cmpinf = fcmp ueq half %fabs, 0xH7C01 158 %cmpzero = fcmp oeq half %x, 0xH0000 159 %class = or i1 %cmpzero, %cmpinf 160 ret i1 %class 161} 162 163; Positive test 164define i1 @ueq_inf_or_ueq_zero(half %x) { 165; CHECK-LABEL: @ueq_inf_or_ueq_zero( 166; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615) 167; CHECK-NEXT: ret i1 [[CLASS]] 168; 169 %fabs = call half @llvm.fabs.f16(half %x) 170 %cmpinf = fcmp ueq half %fabs, 0xH7C00 171 %cmpzero = fcmp ueq half %x, 0xH0000 172 %class = or i1 %cmpzero, %cmpinf 173 ret i1 %class 174} 175 176; Positive test 177define i1 @not_isfinite_and_zero_f16(half %x) { 178; CHECK-LABEL: @not_isfinite_and_zero_f16( 179; CHECK-NEXT: ret i1 false 180; 181 %fabs = call half @llvm.fabs.f16(half %x) 182 %cmpinf = fcmp ueq half %fabs, 0xH7C00 183 %cmpzero = fcmp oeq half %x, 0xH0000 184 %class = and i1 %cmpzero, %cmpinf 185 ret i1 %class 186} 187 188; Negative test 189define i1 @not_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) { 190; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp0( 191; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 192; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 193; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1 194; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 195; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 196; CHECK-NEXT: ret i1 [[CLASS]] 197; 198 %fabs = call half @llvm.fabs.f16(half %x) 199 %cmpinf = fcmp ueq half %fabs, 0xH7C00 200 store i1 %cmpinf, ptr %ptr 201 %cmpzero = fcmp oeq half %x, 0xH0000 202 %class = or i1 %cmpzero, %cmpinf 203 ret i1 %class 204} 205 206; Negative test 207define i1 @not_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) { 208; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp1( 209; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 210; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 211; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 212; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1 213; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 214; CHECK-NEXT: ret i1 [[CLASS]] 215; 216 %fabs = call half @llvm.fabs.f16(half %x) 217 %cmpinf = fcmp ueq half %fabs, 0xH7C00 218 %cmpzero = fcmp oeq half %x, 0xH0000 219 store i1 %cmpzero, ptr %ptr 220 %class = or i1 %cmpzero, %cmpinf 221 ret i1 %class 222} 223 224; Negative test 225define i1 @not_isfinite_or_zero_f16_neg_inf(half %x) { 226; CHECK-LABEL: @not_isfinite_or_zero_f16_neg_inf( 227; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000 228; CHECK-NEXT: ret i1 [[CLASS]] 229; 230 %fabs = call half @llvm.fabs.f16(half %x) 231 %cmpinf = fcmp ueq half %fabs, 0xHFC00 232 %cmpzero = fcmp oeq half %x, 0xH0000 233 %class = or i1 %cmpzero, %cmpinf 234 ret i1 %class 235} 236 237; Negative test 238define i1 @olt_0_or_fabs_ueq_inf(half %x) { 239; CHECK-LABEL: @olt_0_or_fabs_ueq_inf( 240; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543) 241; CHECK-NEXT: ret i1 [[CLASS]] 242; 243 %fabs = call half @llvm.fabs.f16(half %x) 244 %cmpinf = fcmp ueq half %fabs, 0xH7C00 245 %cmpzero = fcmp olt half %x, 0xH0000 246 %class = or i1 %cmpzero, %cmpinf 247 ret i1 %class 248} 249 250; Negative test 251define i1 @oeq_0_or_fabs_ult_inf(half %x) { 252; CHECK-LABEL: @oeq_0_or_fabs_ult_inf( 253; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 254; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[TMP1]], 0xH7C00 255; CHECK-NEXT: ret i1 [[CLASS]] 256; 257 %fabs = call half @llvm.fabs.f16(half %x) 258 %cmpinf = fcmp ult half %fabs, 0xH7C00 259 %cmpzero = fcmp oeq half %x, 0xH0000 260 %class = or i1 %cmpzero, %cmpinf 261 ret i1 %class 262} 263 264; Negative test 265define i1 @not_isfinite_or_zero_f16_multi_not_0(half %x, ptr %ptr) { 266; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_not_0( 267; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 268; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 269; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH3C00 270; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 271; CHECK-NEXT: ret i1 [[CLASS]] 272; 273 %fabs = call half @llvm.fabs.f16(half %x) 274 %cmpinf = fcmp ueq half %fabs, 0xH7C00 275 %cmpzero = fcmp oeq half %x, 1.0 276 %class = or i1 %cmpzero, %cmpinf 277 ret i1 %class 278} 279 280; Negative test 281define i1 @not_isfinite_or_zero_f16_fabs_wrong_val(half %x, half %y) { 282; CHECK-LABEL: @not_isfinite_or_zero_f16_fabs_wrong_val( 283; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]]) 284; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 285; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 286; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 287; CHECK-NEXT: ret i1 [[CLASS]] 288; 289 %fabs = call half @llvm.fabs.f16(half %y) 290 %cmpinf = fcmp ueq half %fabs, 0xH7C00 291 %cmpzero = fcmp oeq half %x, 0xH0000 292 %class = or i1 %cmpzero, %cmpinf 293 ret i1 %class 294} 295 296; Negative test 297define i1 @not_isfinite_or_zero_f16_not_fabs(half %x) { 298; CHECK-LABEL: @not_isfinite_or_zero_f16_not_fabs( 299; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.canonicalize.f16(half [[X:%.*]]) 300; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 301; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 302; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 303; CHECK-NEXT: ret i1 [[CLASS]] 304; 305 %fabs = call half @llvm.canonicalize.f16(half %x) 306 %cmpinf = fcmp ueq half %fabs, 0xH7C00 307 %cmpzero = fcmp oeq half %x, 0xH0000 308 %class = or i1 %cmpzero, %cmpinf 309 ret i1 %class 310} 311 312; -------------------------------------------------------------------- 313; Negated pattern, isfinite(x) && !(x == 0.0) 314; -------------------------------------------------------------------- 315 316; Negation of base pattern, isfinite(x) && !(x == 0.0) 317define i1 @negated_isfinite_or_zero_f16(half %x) { 318; CHECK-LABEL: @negated_isfinite_or_zero_f16( 319; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408) 320; CHECK-NEXT: ret i1 [[NOT_CLASS]] 321; 322 %fabs = call half @llvm.fabs.f16(half %x) 323 %cmpinf = fcmp one half %fabs, 0xH7C00 324 %cmpzero = fcmp une half %x, 0xH0000 325 %not.class = and i1 %cmpzero, %cmpinf 326 ret i1 %not.class 327} 328 329; Commuted !(x == 0.0) && isfinite(x) 330define i1 @negated_isfinite_or_zero_f16_commute_and(half %x) { 331; CHECK-LABEL: @negated_isfinite_or_zero_f16_commute_and( 332; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408) 333; CHECK-NEXT: ret i1 [[NOT_CLASS]] 334; 335 %fabs = call half @llvm.fabs.f16(half %x) 336 %cmpinf = fcmp one half %fabs, 0xH7C00 337 %cmpzero = fcmp une half %x, 0xH0000 338 %not.class = and i1 %cmpinf, %cmpzero 339 ret i1 %not.class 340} 341 342; isfinite(x) && !(x == -0.0) 343define i1 @negated_isfinite_or_zero_f16_negzero(half %x) { 344; CHECK-LABEL: @negated_isfinite_or_zero_f16_negzero( 345; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408) 346; CHECK-NEXT: ret i1 [[NOT_CLASS]] 347; 348 %fabs = call half @llvm.fabs.f16(half %x) 349 %cmpinf = fcmp one half %fabs, 0xH7C00 350 %cmpzero = fcmp une half %x, -0.0 351 %not.class = and i1 %cmpzero, %cmpinf 352 ret i1 %not.class 353} 354 355; Negated pattern 356define <2 x i1> @negated_isfinite_or_zero_v2f16(<2 x half> %x) { 357; CHECK-LABEL: @negated_isfinite_or_zero_v2f16( 358; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408) 359; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]] 360; 361 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 362 %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 363 %cmpzero = fcmp une <2 x half> %x, zeroinitializer 364 %not.class = and <2 x i1> %cmpzero, %cmpinf 365 ret <2 x i1> %not.class 366} 367 368; Negated pattern, commuted vector and 369define <2 x i1> @negated_isfinite_or_zero_v2f16_comumte(<2 x half> %x) { 370; CHECK-LABEL: @negated_isfinite_or_zero_v2f16_comumte( 371; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408) 372; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]] 373; 374 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 375 %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 376 %cmpzero = fcmp une <2 x half> %x, zeroinitializer 377 %not.class = and <2 x i1> %cmpinf, %cmpzero 378 ret <2 x i1> %not.class 379} 380 381; Positive test 382define i1 @negated_isfinite_or_zero_f16_not_une_zero(half %x) { 383; CHECK-LABEL: @negated_isfinite_or_zero_f16_not_une_zero( 384; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408) 385; CHECK-NEXT: ret i1 [[NOT_CLASS]] 386; 387 %fabs = call half @llvm.fabs.f16(half %x) 388 %cmpinf = fcmp one half %fabs, 0xH7C00 389 %cmpzero = fcmp one half %x, 0xH0000 390 %not.class = and i1 %cmpzero, %cmpinf 391 ret i1 %not.class 392} 393 394; Positive test 395define i1 @negated_isfinite_and_zero_f16(half %x) { 396; CHECK-LABEL: @negated_isfinite_and_zero_f16( 397; CHECK-NEXT: ret i1 true 398; 399 %fabs = call half @llvm.fabs.f16(half %x) 400 %cmpinf = fcmp one half %fabs, 0xH7C00 401 %cmpzero = fcmp une half %x, 0xH0000 402 %not.class = or i1 %cmpzero, %cmpinf 403 ret i1 %not.class 404} 405 406; Negative test 407define i1 @negated_isfinite_or_zero_f16_swapped_constants(half %x) { 408; CHECK-LABEL: @negated_isfinite_or_zero_f16_swapped_constants( 409; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 412) 410; CHECK-NEXT: ret i1 [[NOT_CLASS]] 411; 412 %fabs = call half @llvm.fabs.f16(half %x) 413 %cmpzero = fcmp one half %fabs, 0xH0000 414 %cmpinf = fcmp une half %x, 0xH7C00 415 %not.class = and i1 %cmpzero, %cmpinf 416 ret i1 %not.class 417} 418 419; Negative test 420define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) { 421; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0( 422; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 423; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00 424; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1 425; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000 426; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]] 427; CHECK-NEXT: ret i1 [[NOT_CLASS]] 428; 429 %fabs = call half @llvm.fabs.f16(half %x) 430 %cmpinf = fcmp one half %fabs, 0xH7C00 431 store i1 %cmpinf, ptr %ptr 432 %cmpzero = fcmp une half %x, 0xH0000 433 %not.class = and i1 %cmpzero, %cmpinf 434 ret i1 %not.class 435} 436 437; Negative test 438define i1 @negated_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) { 439; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp1( 440; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 441; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00 442; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000 443; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1 444; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]] 445; CHECK-NEXT: ret i1 [[NOT_CLASS]] 446; 447 %fabs = call half @llvm.fabs.f16(half %x) 448 %cmpinf = fcmp one half %fabs, 0xH7C00 449 %cmpzero = fcmp une half %x, 0xH0000 450 store i1 %cmpzero, ptr %ptr 451 %not.class = and i1 %cmpzero, %cmpinf 452 ret i1 %not.class 453} 454 455; Negative test 456define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(half %x) { 457; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf( 458; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411) 459; CHECK-NEXT: ret i1 [[NOT_CLASS]] 460; 461 %fabs = call half @llvm.fabs.f16(half %x) 462 %cmpinf = fcmp une half %fabs, 0xH7C00 463 %cmpzero = fcmp une half %x, 0xH0000 464 %not.class = and i1 %cmpzero, %cmpinf 465 ret i1 %not.class 466} 467 468; Negative test 469define i1 @negated_isfinite_or_zero_f16_fabs_wrong_value(half %x, half %y) { 470; CHECK-LABEL: @negated_isfinite_or_zero_f16_fabs_wrong_value( 471; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]]) 472; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00 473; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X:%.*]], 0xH0000 474; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]] 475; CHECK-NEXT: ret i1 [[NOT_CLASS]] 476; 477 %fabs = call half @llvm.fabs.f16(half %y) 478 %cmpinf = fcmp one half %fabs, 0xH7C00 479 %cmpzero = fcmp une half %x, 0xH0000 480 %not.class = and i1 %cmpzero, %cmpinf 481 ret i1 %not.class 482} 483 484; -------------------------------------------------------------------- 485; Other fcmp to class recognition 486; -------------------------------------------------------------------- 487 488define i1 @fcmp_une_0_or_fcmp_une_inf(half %x) { 489; CHECK-LABEL: @fcmp_une_0_or_fcmp_une_inf( 490; CHECK-NEXT: ret i1 true 491; 492 %cmpzero = fcmp une half %x, 0.0 493 %cmpinf = fcmp une half %x, 0xH7C00 494 %or = or i1 %cmpzero, %cmpinf 495 ret i1 %or 496} 497 498define i1 @fcmp_one_0_and_fcmp_une_fabs_inf(half %x) { 499; CHECK-LABEL: @fcmp_one_0_and_fcmp_une_fabs_inf( 500; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408) 501; CHECK-NEXT: ret i1 [[AND]] 502; 503 %fabs = call half @llvm.fabs.f16(half %x) 504 %cmpzero = fcmp one half %x, 0.0 505 %cmpinf = fcmp une half %fabs, 0xH7C00 506 %and = and i1 %cmpzero, %cmpinf 507 ret i1 %and 508} 509 510define i1 @fcmp_une_0_and_fcmp_une_fabs_inf(half %x) { 511; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_fabs_inf( 512; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411) 513; CHECK-NEXT: ret i1 [[AND]] 514; 515 %fabs = call half @llvm.fabs.f16(half %x) 516 %cmpzero = fcmp une half %x, 0.0 517 %cmpinf = fcmp une half %fabs, 0xH7C00 518 %and = and i1 %cmpzero, %cmpinf 519 ret i1 %and 520} 521 522define i1 @fcmp_une_0_and_fcmp_une_neginf(half %x) { 523; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_neginf( 524; CHECK-NEXT: ret i1 true 525; 526 %cmpzero = fcmp une half %x, 0.0 527 %cmpinf = fcmp une half %x, 0xHFC00 528 %or = or i1 %cmpzero, %cmpinf 529 ret i1 %or 530} 531 532define i1 @issubnormal_or_inf(half %x) { 533; CHECK-LABEL: @issubnormal_or_inf( 534; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756) 535; CHECK-NEXT: ret i1 [[CLASS]] 536; 537 %fabs = call half @llvm.fabs.f16(half %x) 538 %cmpinf = fcmp oeq half %fabs, 0xH7C00 539 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 540 %class = or i1 %cmp.smallest.normal, %cmpinf 541 ret i1 %class 542} 543 544define i1 @olt_smallest_normal_or_inf(half %x) { 545; CHECK-LABEL: @olt_smallest_normal_or_inf( 546; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 764) 547; CHECK-NEXT: ret i1 [[CLASS]] 548; 549 %fabs = call half @llvm.fabs.f16(half %x) 550 %cmpinf = fcmp oeq half %fabs, 0xH7C00 551 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 ; missing fabs 552 %class = or i1 %cmp.smallest.normal, %cmpinf 553 ret i1 %class 554} 555 556define i1 @not_issubnormal_or_inf(half %x) { 557; CHECK-LABEL: @not_issubnormal_or_inf( 558; CHECK-NEXT: [[NOT:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 267) 559; CHECK-NEXT: ret i1 [[NOT]] 560; 561 %fabs = call half @llvm.fabs.f16(half %x) 562 %cmpinf = fcmp une half %fabs, 0xH7C00 563 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400 564 %not = and i1 %cmp.smallest.normal, %cmpinf 565 ret i1 %not 566} 567 568define i1 @issubnormal_uge_or_inf(half %x) { 569; CHECK-LABEL: @issubnormal_uge_or_inf( 570; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783) 571; CHECK-NEXT: ret i1 [[CLASS]] 572; 573 %fabs = call half @llvm.fabs.f16(half %x) 574 %cmpinf = fcmp oeq half %fabs, 0xH7C00 575 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400 576 %class = or i1 %cmp.smallest.normal, %cmpinf 577 ret i1 %class 578} 579 580; Negative test, not smallest normal 581define i1 @issubnormal_or_inf_wrong_val(half %x) { 582; CHECK-LABEL: @issubnormal_or_inf_wrong_val( 583; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 584; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00 585; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0401 586; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]] 587; CHECK-NEXT: ret i1 [[CLASS]] 588; 589 %fabs = call half @llvm.fabs.f16(half %x) 590 %cmpinf = fcmp oeq half %fabs, 0xH7C00 591 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0401 592 %class = or i1 %cmp.smallest.normal, %cmpinf 593 ret i1 %class 594} 595 596define i1 @issubnormal_or_inf_neg_smallest_normal(half %x) { 597; CHECK-LABEL: @issubnormal_or_inf_neg_smallest_normal( 598; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 599; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00 600; CHECK-NEXT: ret i1 [[CMPINF]] 601; 602 %fabs = call half @llvm.fabs.f16(half %x) 603 %cmpinf = fcmp oeq half %fabs, 0xH7C00 604 %cmp.smallest.normal = fcmp olt half %fabs, 0xH8400 605 %class = or i1 %cmp.smallest.normal, %cmpinf 606 ret i1 %class 607} 608 609define i1 @fneg_fabs_olt_neg_smallest_normal_or_inf(half %x) { 610; CHECK-LABEL: @fneg_fabs_olt_neg_smallest_normal_or_inf( 611; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 612; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00 613; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp ogt half [[FABS]], 0xH0400 614; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]] 615; CHECK-NEXT: ret i1 [[CLASS]] 616; 617 %fabs = call half @llvm.fabs.f16(half %x) 618 %cmpinf = fcmp oeq half %fabs, 0xH7C00 619 %fneg.fabs = fneg half %fabs 620 %cmp.smallest.normal = fcmp olt half %fneg.fabs, 0xH8400 621 %class = or i1 %cmp.smallest.normal, %cmpinf 622 ret i1 %class 623} 624 625define i1 @issubnormal_or_finite_olt(half %x) { 626; CHECK-LABEL: @issubnormal_or_finite_olt( 627; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 628; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00 629; CHECK-NEXT: ret i1 [[OR]] 630; 631 %fabs = call half @llvm.fabs.f16(half %x) 632 %cmpinf = fcmp olt half %fabs, 0xH7C00 633 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 634 %or = or i1 %cmp.smallest.normal, %cmpinf 635 ret i1 %or 636} 637 638; inf | nan | zero | subnormal 639define i1 @issubnormal_or_finite_uge(half %x) { 640; CHECK-LABEL: @issubnormal_or_finite_uge( 641; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 759) 642; CHECK-NEXT: ret i1 [[OR]] 643; 644 %fabs = call half @llvm.fabs.f16(half %x) 645 %cmpinf = fcmp uge half %fabs, 0xH7C00 646 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 647 %or = or i1 %cmp.smallest.normal, %cmpinf 648 ret i1 %or 649} 650 651define i1 @issubnormal_and_finite_olt(half %x) { 652; CHECK-LABEL: @issubnormal_and_finite_olt( 653; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) 654; CHECK-NEXT: ret i1 [[AND]] 655; 656 %fabs = call half @llvm.fabs.f16(half %x) 657 %cmpinf = fcmp olt half %fabs, 0xH7C00 658 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 659 %and = and i1 %cmp.smallest.normal, %cmpinf 660 ret i1 %and 661} 662 663define i1 @not_zero_and_subnormal(half %x) { 664; CHECK-LABEL: @not_zero_and_subnormal( 665; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 666; CHECK-NEXT: ret i1 [[OR]] 667; 668 %fabs = call half @llvm.fabs.f16(half %x) 669 %cmp.zero = fcmp one half %fabs, 0.0 670 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 671 %or = or i1 %cmp.smallest.normal, %cmp.zero 672 ret i1 %or 673} 674 675define i1 @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(half %x) { 676; CHECK-LABEL: @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm( 677; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783) 678; CHECK-NEXT: ret i1 [[OR]] 679; 680 %fabs = call half @llvm.fabs.f16(half %x) 681 %cmpinf = fcmp uge half %fabs, 0xH7C00 682 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400 683 %or = or i1 %cmp.smallest.normal, %cmpinf 684 ret i1 %or 685} 686 687; -------------------------------------------------------------------- 688; Test ord/uno 689; -------------------------------------------------------------------- 690 691define i1 @is_finite_and_ord(half %x) { 692; CHECK-LABEL: @is_finite_and_ord( 693; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 694; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[FABS]], 0xH7C00 695; CHECK-NEXT: ret i1 [[AND]] 696; 697 %fabs = call half @llvm.fabs.f16(half %x) 698 %is.finite = fcmp ueq half %fabs, 0xH7C00 699 %ord = fcmp ord half %x, %x 700 %and = and i1 %ord, %is.finite 701 ret i1 %and 702} 703 704define i1 @is_finite_and_uno(half %x) { 705; CHECK-LABEL: @is_finite_and_uno( 706; CHECK-NEXT: [[AND:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 707; CHECK-NEXT: ret i1 [[AND]] 708; 709 %fabs = call half @llvm.fabs.f16(half %x) 710 %is.finite = fcmp ueq half %fabs, 0xH7C00 711 %uno = fcmp uno half %x, %x 712 %and = and i1 %uno, %is.finite 713 ret i1 %and 714} 715 716define i1 @is_finite_or_ord(half %x) { 717; CHECK-LABEL: @is_finite_or_ord( 718; CHECK-NEXT: ret i1 true 719; 720 %fabs = call half @llvm.fabs.f16(half %x) 721 %is.finite = fcmp ueq half %fabs, 0xH7C00 722 %ord = fcmp ord half %x, %x 723 %or = or i1 %ord, %is.finite 724 ret i1 %or 725} 726 727define i1 @is_finite_or_uno(half %x) { 728; CHECK-LABEL: @is_finite_or_uno( 729; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 730; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00 731; CHECK-NEXT: ret i1 [[OR]] 732; 733 %fabs = call half @llvm.fabs.f16(half %x) 734 %is.finite = fcmp ueq half %fabs, 0xH7C00 735 %uno = fcmp uno half %x, %x 736 %or = or i1 %uno, %is.finite 737 ret i1 %or 738} 739 740define i1 @oeq_isinf_or_uno(half %x) { 741; CHECK-LABEL: @oeq_isinf_or_uno( 742; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 743; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00 744; CHECK-NEXT: ret i1 [[CLASS]] 745; 746 %fabs = call half @llvm.fabs.f16(half %x) 747 %cmpinf = fcmp oeq half %fabs, 0xH7C00 748 %uno = fcmp uno half %x, 0xH0000 749 %class = or i1 %cmpinf, %uno 750 ret i1 %class 751} 752 753define i1 @oeq_isinf_or_ord(half %x) { 754; CHECK-LABEL: @oeq_isinf_or_ord( 755; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 756; CHECK-NEXT: ret i1 [[CLASS]] 757; 758 %fabs = call half @llvm.fabs.f16(half %x) 759 %cmpinf = fcmp oeq half %fabs, 0xH7C00 760 %uno = fcmp ord half %x, 0xH0000 761 %class = or i1 %cmpinf, %uno 762 ret i1 %class 763} 764 765define i1 @oeq_isinf_and_uno(half %x) { 766; CHECK-LABEL: @oeq_isinf_and_uno( 767; CHECK-NEXT: ret i1 false 768; 769 %fabs = call half @llvm.fabs.f16(half %x) 770 %cmpinf = fcmp oeq half %fabs, 0xH7C00 771 %uno = fcmp uno half %x, 0xH0000 772 %and = and i1 %cmpinf, %uno 773 ret i1 %and 774} 775 776define i1 @oeq_isinf_and_ord(half %x) { 777; CHECK-LABEL: @oeq_isinf_and_ord( 778; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 779; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00 780; CHECK-NEXT: ret i1 [[AND]] 781; 782 %fabs = call half @llvm.fabs.f16(half %x) 783 %cmpinf = fcmp oeq half %fabs, 0xH7C00 784 %uno = fcmp ord half %x, 0xH0000 785 %and = and i1 %cmpinf, %uno 786 ret i1 %and 787} 788 789; -------------------------------------------------------------------- 790; isnormal(x) || x == 0.0 791; -------------------------------------------------------------------- 792 793define i1 @isnormal_or_zero(half %x) #0 { 794; CHECK-LABEL: @isnormal_or_zero( 795; CHECK-NEXT: entry: 796; CHECK-NEXT: [[AND1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360) 797; CHECK-NEXT: ret i1 [[AND1]] 798; 799entry: 800 %iseq = fcmp ord half %x, 0xH0000 801 %fabs = tail call half @llvm.fabs.f16(half %x) 802 %isinf = fcmp ult half %fabs, 0xH7C00 803 %isnormal = fcmp uge half %fabs, 0xH0400 804 %and = and i1 %iseq, %isinf 805 %and1 = and i1 %isnormal, %and 806 %cmp = fcmp oeq half %x, 0xH0000 807 %spec.select = or i1 %cmp, %and1 808 ret i1 %spec.select 809} 810 811define i1 @isnormal_uge_or_zero_oeq(half %x) #0 { 812; CHECK-LABEL: @isnormal_uge_or_zero_oeq( 813; CHECK-NEXT: entry: 814; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 879) 815; CHECK-NEXT: ret i1 [[OR]] 816; 817entry: 818 %fabs = tail call half @llvm.fabs.f16(half %x) 819 %is.normal = fcmp uge half %fabs, 0xH0400 820 %is.zero = fcmp oeq half %x, 0xH0000 821 %or = or i1 %is.normal, %is.zero 822 ret i1 %or 823} 824 825; -------------------------------------------------------------------- 826; smallest_normal check part of isnormal(x) 827; -------------------------------------------------------------------- 828 829; -> ord 830define i1 @isnormalinf_or_ord(half %x) #0 { 831; CHECK-LABEL: @isnormalinf_or_ord( 832; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 833; CHECK-NEXT: ret i1 [[OR]] 834; 835 %fabs = call half @llvm.fabs.f16(half %x) 836 %is.normal.inf = fcmp oge half %fabs, 0xH0400 837 %is.ord = fcmp ord half %x, 0xH0000 838 %or = or i1 %is.normal.inf, %is.ord 839 ret i1 %or 840} 841 842; -> ord 843define i1 @ord_or_isnormalinf(half %x) #0 { 844; CHECK-LABEL: @ord_or_isnormalinf( 845; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 846; CHECK-NEXT: ret i1 [[OR]] 847; 848 %fabs = call half @llvm.fabs.f16(half %x) 849 %is.normal.inf = fcmp oge half %fabs, 0xH0400 850 %is.ord = fcmp ord half %x, 0xH0000 851 %or = or i1 %is.ord, %is.normal.inf 852 ret i1 %or 853} 854 855; No fabs 856; -> iszero 857define i1 @une_or_oge_smallest_normal(half %x) #0 { 858; CHECK-LABEL: @une_or_oge_smallest_normal( 859; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH0000 860; CHECK-NEXT: ret i1 [[OR]] 861; 862 %is.normal.inf = fcmp oge half %x, 0xH0400 863 %is.une = fcmp une half %x, 0xH0000 864 %or = or i1 %is.une, %is.normal.inf 865 ret i1 %or 866} 867 868; -> normal | inf 869define i1 @isnormalinf_or_inf(half %x) #0 { 870; CHECK-LABEL: @isnormalinf_or_inf( 871; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780) 872; CHECK-NEXT: ret i1 [[OR]] 873; 874 %fabs = call half @llvm.fabs.f16(half %x) 875 %is.normal.inf = fcmp oge half %fabs, 0xH0400 876 %is.inf = fcmp oeq half %fabs, 0xH7C00 877 %or = or i1 %is.normal.inf, %is.inf 878 ret i1 %or 879} 880 881; -> pinf | pnormal 882define i1 @posisnormalinf_or_posinf(half %x) #0 { 883; CHECK-LABEL: @posisnormalinf_or_posinf( 884; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772) 885; CHECK-NEXT: ret i1 [[OR]] 886; 887 %fabs = call half @llvm.fabs.f16(half %x) 888 %is.pos.normal.inf = fcmp oge half %x, 0xH0400 889 %is.inf = fcmp oeq half %fabs, 0xH7C00 890 %or = or i1 %is.pos.normal.inf, %is.inf 891 ret i1 %or 892} 893 894; -> normal | inf 895define i1 @isnormalinf_or_posinf(half %x) #0 { 896; CHECK-LABEL: @isnormalinf_or_posinf( 897; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780) 898; CHECK-NEXT: ret i1 [[OR]] 899; 900 %fabs = call half @llvm.fabs.f16(half %x) 901 %is.normal.inf = fcmp oge half %fabs, 0xH0400 902 %is.pos.inf = fcmp oeq half %x, 0xH7C00 903 %or = or i1 %is.normal.inf, %is.pos.inf 904 ret i1 %or 905} 906 907; -> pinf|ninf 908define i1 @isnormalinf_and_inf(half %x) #0 { 909; CHECK-LABEL: @isnormalinf_and_inf( 910; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 911; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00 912; CHECK-NEXT: ret i1 [[AND]] 913; 914 %fabs = call half @llvm.fabs.f16(half %x) 915 %is.normal.inf = fcmp oge half %fabs, 0xH0400 916 %is.inf = fcmp oeq half %fabs, 0xH7C00 917 %and = and i1 %is.normal.inf, %is.inf 918 ret i1 %and 919} 920 921; -> pinf 922define i1 @posisnormalinf_and_posinf(half %x) #0 { 923; CHECK-LABEL: @posisnormalinf_and_posinf( 924; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 925; CHECK-NEXT: ret i1 [[AND]] 926; 927 %fabs = call half @llvm.fabs.f16(half %x) 928 %is.pos.normal.inf = fcmp oge half %x, 0xH0400 929 %is.inf = fcmp oeq half %fabs, 0xH7C00 930 %and = and i1 %is.pos.normal.inf, %is.inf 931 ret i1 %and 932} 933 934; -> pinf 935define i1 @isnormalinf_and_posinf(half %x) #0 { 936; CHECK-LABEL: @isnormalinf_and_posinf( 937; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 938; CHECK-NEXT: ret i1 [[AND]] 939; 940 %fabs = call half @llvm.fabs.f16(half %x) 941 %is.normal.inf = fcmp oge half %fabs, 0xH0400 942 %is.pos.inf = fcmp oeq half %x, 0xH7C00 943 %and = and i1 %is.normal.inf, %is.pos.inf 944 ret i1 %and 945} 946 947; -------------------------------------------------------------------- 948; smallest_normal check part of isnormal(x) with inverted compare 949; -------------------------------------------------------------------- 950 951; -> true 952define i1 @not_isnormalinf_or_ord(half %x) #0 { 953; CHECK-LABEL: @not_isnormalinf_or_ord( 954; CHECK-NEXT: ret i1 true 955; 956 %fabs = call half @llvm.fabs.f16(half %x) 957 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400 958 %is.ord = fcmp ord half %x, 0xH0000 959 %or = or i1 %not.is.normal.inf, %is.ord 960 ret i1 %or 961} 962 963; -> subnormal | zero 964define i1 @not_isnormalinf_and_ord(half %x) #0 { 965; CHECK-LABEL: @not_isnormalinf_and_ord( 966; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) 967; CHECK-NEXT: ret i1 [[AND]] 968; 969 %fabs = call half @llvm.fabs.f16(half %x) 970 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400 971 %is.ord = fcmp ord half %x, 0xH0000 972 %and = and i1 %not.is.normal.inf, %is.ord 973 ret i1 %and 974} 975 976; -> ~ninf 977define i1 @not_isnormalinf_or_inf(half %x) #0 { 978; CHECK-LABEL: @not_isnormalinf_or_inf( 979; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 980; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00 981; CHECK-NEXT: ret i1 [[OR]] 982; 983 %fabs = call half @llvm.fabs.f16(half %x) 984 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400 985 %is.inf = fcmp olt half %fabs, 0xH7C00 986 %or = or i1 %not.is.normal.inf, %is.inf 987 ret i1 %or 988} 989 990; -> subnormal | zero | nan 991define i1 @not_isnormalinf_or_uno(half %x) #0 { 992; CHECK-LABEL: @not_isnormalinf_or_uno( 993; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 994; CHECK-NEXT: [[OR:%.*]] = fcmp ult half [[FABS]], 0xH0400 995; CHECK-NEXT: ret i1 [[OR]] 996; 997 %fabs = call half @llvm.fabs.f16(half %x) 998 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400 999 %is.uno = fcmp uno half %fabs, 0.0 1000 %or = or i1 %not.is.normal.inf, %is.uno 1001 ret i1 %or 1002} 1003 1004; -> subnormal | zero | nan 1005define i1 @not_isnormalinf_or_uno_nofabs(half %x) #0 { 1006; CHECK-LABEL: @not_isnormalinf_or_uno_nofabs( 1007; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1008; CHECK-NEXT: [[OR:%.*]] = fcmp ult half [[FABS]], 0xH0400 1009; CHECK-NEXT: ret i1 [[OR]] 1010; 1011 %fabs = call half @llvm.fabs.f16(half %x) 1012 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400 1013 %is.uno = fcmp uno half %x, 0.0 1014 %or = or i1 %not.is.normal.inf, %is.uno 1015 ret i1 %or 1016} 1017 1018; -> ~pnormal 1019define i1 @not_negisnormalinf_or_inf(half %x) #0 { 1020; CHECK-LABEL: @not_negisnormalinf_or_inf( 1021; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767) 1022; CHECK-NEXT: ret i1 [[OR]] 1023; 1024 %fabs = call half @llvm.fabs.f16(half %x) 1025 %not.is.neg.normal.inf = fcmp ult half %x, 0xH0400 1026 %is.inf = fcmp oeq half %fabs, 0xH7C00 1027 %or = or i1 %not.is.neg.normal.inf, %is.inf 1028 ret i1 %or 1029} 1030 1031; -> ~pnormal 1032define i1 @not_negisnormalinf_or_posinf(half %x) #0 { 1033; CHECK-LABEL: @not_negisnormalinf_or_posinf( 1034; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767) 1035; CHECK-NEXT: ret i1 [[OR]] 1036; 1037 %not.is.pos.normal.inf = fcmp ult half %x, 0xH0400 1038 %is.inf = fcmp oeq half %x, 0xH7C00 1039 %or = or i1 %not.is.pos.normal.inf, %is.inf 1040 ret i1 %or 1041} 1042 1043; -> ninf | nnormal 1044define i1 @not_isposnormalinf_and_isnormalinf(half %x) #0 { 1045; CHECK-LABEL: @not_isposnormalinf_and_isnormalinf( 1046; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 12) 1047; CHECK-NEXT: ret i1 [[AND]] 1048; 1049 %not.is.pos.normal.inf = fcmp ult half %x, 0xH0400 1050 %fabs = call half @llvm.fabs.f16(half %x) 1051 %is.normal.inf = fcmp oge half %fabs, 0xH0400 1052 %and = and i1 %not.is.pos.normal.inf, %is.normal.inf 1053 ret i1 %and 1054} 1055 1056; -> ord 1057define i1 @olt_smallest_normal_or_ord(half %x) #0 { 1058; CHECK-LABEL: @olt_smallest_normal_or_ord( 1059; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1060; CHECK-NEXT: ret i1 [[CLASS]] 1061; 1062 %ord = fcmp ord half %x, 0.0 1063 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1064 %class = or i1 %cmp.smallest.normal, %ord 1065 ret i1 %class 1066} 1067 1068; -> ~pinf 1069define i1 @olt_smallest_normal_or_uno(half %x) #0 { 1070; CHECK-LABEL: @olt_smallest_normal_or_uno( 1071; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255) 1072; CHECK-NEXT: ret i1 [[CLASS]] 1073; 1074 %uno = fcmp uno half %x, 0.0 1075 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1076 %class = or i1 %cmp.smallest.normal, %uno 1077 ret i1 %class 1078} 1079 1080define i1 @olt_smallest_normal_or_finite(half %x) #0 { 1081; CHECK-LABEL: @olt_smallest_normal_or_finite( 1082; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00 1083; CHECK-NEXT: ret i1 [[CLASS]] 1084; 1085 %fabs = call half @llvm.fabs.f16(half %x) 1086 %is.finite = fcmp olt half %fabs, 0xH7C00 1087 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1088 %class = or i1 %cmp.smallest.normal, %is.finite 1089 ret i1 %class 1090} 1091 1092define i1 @uge_smallest_normal_or_ord(half %x) #0 { 1093; CHECK-LABEL: @uge_smallest_normal_or_ord( 1094; CHECK-NEXT: ret i1 true 1095; 1096 %ord = fcmp ord half %x, 0.0 1097 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1098 %class = or i1 %cmp.smallest.normal, %ord 1099 ret i1 %class 1100} 1101 1102; -> nan | pnormal | pinf 1103define i1 @uge_smallest_normal_or_uno(half %x) #0 { 1104; CHECK-LABEL: @uge_smallest_normal_or_uno( 1105; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp uge half [[X:%.*]], 0xH0400 1106; CHECK-NEXT: ret i1 [[CMP_SMALLEST_NORMAL]] 1107; 1108 %uno = fcmp uno half %x, 0.0 1109 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1110 %class = or i1 %cmp.smallest.normal, %uno 1111 ret i1 %class 1112} 1113 1114; -> uno 1115define i1 @uge_smallest_normal_and_uno(half %x) #0 { 1116; CHECK-LABEL: @uge_smallest_normal_and_uno( 1117; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 1118; CHECK-NEXT: ret i1 [[CLASS]] 1119; 1120 %uno = fcmp uno half %x, 0.0 1121 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1122 %class = and i1 %cmp.smallest.normal, %uno 1123 ret i1 %class 1124} 1125 1126; -> true 1127define i1 @olt_infinity_or_finite(half %x) #0 { 1128; CHECK-LABEL: @olt_infinity_or_finite( 1129; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00 1130; CHECK-NEXT: ret i1 [[CLASS]] 1131; 1132 %lt.infinity = fcmp olt half %x, 0xH7C00 1133 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1134 %class = or i1 %cmp.smallest.normal, %lt.infinity 1135 ret i1 %class 1136} 1137 1138; -> zero|subnormal|normal 1139define i1 @olt_infinity_and_finite(half %x) #0 { ; bustttedddd 1140; CHECK-LABEL: @olt_infinity_and_finite( 1141; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252) 1142; CHECK-NEXT: ret i1 [[CLASS]] 1143; 1144 %lt.infinity = fcmp olt half %x, 0xH7C00 1145 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1146 %class = and i1 %cmp.smallest.normal, %lt.infinity 1147 ret i1 %class 1148} 1149 1150; -> ord 1151define i1 @olt_infinity_or_ord(half %x) #0 { 1152; CHECK-LABEL: @olt_infinity_or_ord( 1153; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1154; CHECK-NEXT: ret i1 [[CLASS]] 1155; 1156 %lt.infinity = fcmp olt half %x, 0xH7C00 1157 %ord = fcmp ord half %x, 0xH0400 1158 %class = or i1 %lt.infinity, %ord 1159 ret i1 %class 1160} 1161 1162; -> ~posinf 1163define i1 @olt_infinity_or_uno(half %x) #0 { 1164; CHECK-LABEL: @olt_infinity_or_uno( 1165; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00 1166; CHECK-NEXT: ret i1 [[CLASS]] 1167; 1168 %lt.infinity = fcmp olt half %x, 0xH7C00 1169 %uno = fcmp uno half %x, 0xH0400 1170 %class = or i1 %lt.infinity, %uno 1171 ret i1 %class 1172} 1173 1174define i1 @olt_infinity_or_subnormal(half %x) #0 { 1175; CHECK-LABEL: @olt_infinity_or_subnormal( 1176; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00 1177; CHECK-NEXT: ret i1 [[CLASS]] 1178; 1179 %lt.infinity = fcmp olt half %x, 0xH7C00 1180 %fabs = call half @llvm.fabs.f16(half %x) 1181 %is.subnormal = fcmp olt half %fabs, 0xH0400 1182 %class = or i1 %lt.infinity, %is.subnormal 1183 ret i1 %class 1184} 1185 1186define i1 @olt_infinity_and_subnormal(half %x) #0 { 1187; CHECK-LABEL: @olt_infinity_and_subnormal( 1188; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) 1189; CHECK-NEXT: ret i1 [[CLASS]] 1190; 1191 %lt.infinity = fcmp olt half %x, 0xH7C00 1192 %fabs = call half @llvm.fabs.f16(half %x) 1193 %is.subnormal = fcmp olt half %fabs, 0xH0400 1194 %class = and i1 %lt.infinity, %is.subnormal 1195 ret i1 %class 1196} 1197 1198define i1 @olt_infinity_and_not_subnormal(half %x) #0 { 1199; CHECK-LABEL: @olt_infinity_and_not_subnormal( 1200; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 268) 1201; CHECK-NEXT: ret i1 [[CLASS]] 1202; 1203 %lt.infinity = fcmp olt half %x, 0xH7C00 1204 %fabs = call half @llvm.fabs.f16(half %x) 1205 %is.subnormal = fcmp olt half %fabs, 0xH0400 1206 %not.subnormal = xor i1 %is.subnormal, true 1207 %class = and i1 %lt.infinity, %not.subnormal 1208 ret i1 %class 1209} 1210 1211; -> ninf 1212define i1 @olt_infinity_and_ueq_inf(half %x) #0 { 1213; CHECK-LABEL: @olt_infinity_and_ueq_inf( 1214; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1215; CHECK-NEXT: ret i1 [[CLASS]] 1216; 1217 %lt.infinity = fcmp olt half %x, 0xH7C00 1218 %fabs = call half @llvm.fabs.f16(half %x) 1219 %eq.inf = fcmp ueq half %fabs, 0xH7C00 1220 %class = and i1 %lt.infinity, %eq.inf 1221 ret i1 %class 1222} 1223 1224; -> true 1225define i1 @olt_infinity_or_ueq_inf(half %x) #0 { 1226; CHECK-LABEL: @olt_infinity_or_ueq_inf( 1227; CHECK-NEXT: ret i1 true 1228; 1229 %lt.infinity = fcmp olt half %x, 0xH7C00 1230 %eq.inf = fcmp ueq half %x, 0xH7C00 1231 %class = or i1 %lt.infinity, %eq.inf 1232 ret i1 %class 1233} 1234 1235; -> pnormal 1236define i1 @olt_smallest_normal_or_ueq_inf(half %x) #0 { 1237; CHECK-LABEL: @olt_smallest_normal_or_ueq_inf( 1238; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767) 1239; CHECK-NEXT: ret i1 [[CLASS]] 1240; 1241 %lt.normal = fcmp olt half %x, 0xH0400 1242 %eq.inf = fcmp ueq half %x, 0xH7C00 1243 %class = or i1 %lt.normal, %eq.inf 1244 ret i1 %class 1245} 1246 1247; -> ~pinf 1248define i1 @olt_smallest_normal_or_une_inf(half %x) #0 { 1249; CHECK-LABEL: @olt_smallest_normal_or_une_inf( 1250; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00 1251; CHECK-NEXT: ret i1 [[CLASS]] 1252; 1253 %lt.normal = fcmp olt half %x, 0xH0400 1254 %eq.inf = fcmp une half %x, 0xH7C00 1255 %class = or i1 %lt.normal, %eq.inf 1256 ret i1 %class 1257} 1258 1259; -> ninf | nnormal | subnormal | zero 1260define i1 @olt_smallest_normal_and_une_inf(half %x) #0 { 1261; CHECK-LABEL: @olt_smallest_normal_and_une_inf( 1262; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252) 1263; CHECK-NEXT: ret i1 [[CLASS]] 1264; 1265 %lt.normal = fcmp olt half %x, 0xH0400 1266 %eq.inf = fcmp une half %x, 0xH7C00 1267 %class = and i1 %lt.normal, %eq.inf 1268 ret i1 %class 1269} 1270 1271define i1 @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(half %x) #0 { 1272; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal( 1273; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252) 1274; CHECK-NEXT: ret i1 [[CLASS]] 1275; 1276 %lt.normal = fcmp olt half %x, 0xH0400 1277 %eq.inf = fcmp une half %x, 0xH7C00 1278 %class = and i1 %lt.normal, %eq.inf 1279 %eq.normal = fcmp oeq half %x, 0xH0400 1280 %eq.largest.normal = or i1 %eq.normal, %class 1281 ret i1 %class 1282} 1283 1284define i1 @olt_smallest_normal_and_une_inf_or_one_smallest_normal(half %x) #0 { 1285; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_one_smallest_normal( 1286; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252) 1287; CHECK-NEXT: ret i1 [[CLASS]] 1288; 1289 %lt.normal = fcmp olt half %x, 0xH0400 1290 %eq.inf = fcmp une half %x, 0xH7C00 1291 %class = and i1 %lt.normal, %eq.inf 1292 %ne.normal = fcmp one half %x, 0xH0400 1293 %eq.largest.normal = or i1 %ne.normal, %class 1294 ret i1 %class 1295} 1296 1297define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 { 1298; CHECK-LABEL: @oge_fabs_eq_inf_and_ord( 1299; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1300; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00 1301; CHECK-NEXT: ret i1 [[AND]] 1302; 1303 %fabs = call half @llvm.fabs.f16(half %x) 1304 %oge.fabs.inf = fcmp oge half %fabs, 0xH7C00 1305 %ord = fcmp ord half %x, 0xH0000 1306 %and = and i1 %oge.fabs.inf, %ord 1307 ret i1 %and 1308} 1309 1310define i1 @oge_eq_inf_and_ord(half %x) #0 { 1311; CHECK-LABEL: @oge_eq_inf_and_ord( 1312; CHECK-NEXT: [[OGE_FABS_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 1313; CHECK-NEXT: ret i1 [[OGE_FABS_INF]] 1314; 1315 %oge.fabs.inf = fcmp oge half %x, 0xH7C00 1316 %ord = fcmp ord half %x, 0xH0000 1317 %and = and i1 %oge.fabs.inf, %ord 1318 ret i1 %and 1319} 1320 1321define i1 @oge_fabs_eq_inf_or_uno(half %x) #0 { 1322; CHECK-LABEL: @oge_fabs_eq_inf_or_uno( 1323; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1324; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00 1325; CHECK-NEXT: ret i1 [[OR]] 1326; 1327 %fabs = call half @llvm.fabs.f16(half %x) 1328 %oge.fabs.inf = fcmp oge half %fabs, 0xH7C00 1329 %uno = fcmp uno half %x, 0xH0000 1330 %or = or i1 %oge.fabs.inf, %uno 1331 ret i1 %or 1332} 1333 1334define i1 @oge_eq_inf_or_uno(half %x) #0 { 1335; CHECK-LABEL: @oge_eq_inf_or_uno( 1336; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 1337; CHECK-NEXT: ret i1 [[OR]] 1338; 1339 %oge.fabs.inf = fcmp oge half %x, 0xH7C00 1340 %uno = fcmp uno half %x, 0xH0000 1341 %or = or i1 %oge.fabs.inf, %uno 1342 ret i1 %or 1343} 1344 1345define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 { 1346; CHECK-LABEL: @ult_fabs_eq_inf_and_ord( 1347; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1348; CHECK-NEXT: [[AND:%.*]] = fcmp one half [[FABS]], 0xH7C00 1349; CHECK-NEXT: ret i1 [[AND]] 1350; 1351 %fabs = call half @llvm.fabs.f16(half %x) 1352 %ult.fabs.inf = fcmp ult half %fabs, 0xH7C00 1353 %ord = fcmp ord half %x, 0xH0000 1354 %and = and i1 %ult.fabs.inf, %ord 1355 ret i1 %and 1356} 1357 1358define i1 @ult_eq_inf_and_ord(half %x) #0 { 1359; CHECK-LABEL: @ult_eq_inf_and_ord( 1360; CHECK-NEXT: [[AND:%.*]] = fcmp one half [[X:%.*]], 0xH7C00 1361; CHECK-NEXT: ret i1 [[AND]] 1362; 1363 %ult.fabs.inf = fcmp ult half %x, 0xH7C00 1364 %ord = fcmp ord half %x, 0xH0000 1365 %and = and i1 %ult.fabs.inf, %ord 1366 ret i1 %and 1367} 1368 1369define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 { 1370; CHECK-LABEL: @ult_fabs_eq_inf_or_uno( 1371; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1372; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00 1373; CHECK-NEXT: ret i1 [[OR]] 1374; 1375 %fabs = call half @llvm.fabs.f16(half %x) 1376 %ult.fabs.inf = fcmp ult half %fabs, 0xH7C00 1377 %uno = fcmp uno half %x, 0xH0000 1378 %or = or i1 %ult.fabs.inf, %uno 1379 ret i1 %or 1380} 1381 1382define i1 @ult_eq_inf_or_uno(half %x) #0 { 1383; CHECK-LABEL: @ult_eq_inf_or_uno( 1384; CHECK-NEXT: [[ULT_FABS_INF:%.*]] = fcmp une half [[X:%.*]], 0xH7C00 1385; CHECK-NEXT: ret i1 [[ULT_FABS_INF]] 1386; 1387 %ult.fabs.inf = fcmp ult half %x, 0xH7C00 1388 %uno = fcmp uno half %x, 0xH0000 1389 %or = or i1 %ult.fabs.inf, %uno 1390 ret i1 %or 1391} 1392 1393 1394; Can't do anything with this 1395define i1 @oeq_neginfinity_or_oeq_smallest_normal(half %x) #0 { 1396; CHECK-LABEL: @oeq_neginfinity_or_oeq_smallest_normal( 1397; CHECK-NEXT: [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1398; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400 1399; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[OEQ_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]] 1400; CHECK-NEXT: ret i1 [[CLASS]] 1401; 1402 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1403 %cmp.smallest.normal = fcmp oeq half %x, 0xH0400 1404 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal 1405 ret i1 %class 1406} 1407 1408; -> ninf | fcZero | fcSubnormal 1409define i1 @oeq_neginfinity_or_olt_smallest_normal(half %x) #0 { 1410; CHECK-LABEL: @oeq_neginfinity_or_olt_smallest_normal( 1411; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252) 1412; CHECK-NEXT: ret i1 [[CLASS]] 1413; 1414 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1415 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1416 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal 1417 ret i1 %class 1418} 1419 1420; -> ninf 1421define i1 @oeq_neginfinity_and_olt_smallest_normal(half %x) #0 { 1422; CHECK-LABEL: @oeq_neginfinity_and_olt_smallest_normal( 1423; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1424; CHECK-NEXT: ret i1 [[CLASS]] 1425; 1426 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1427 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1428 %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal 1429 ret i1 %class 1430} 1431 1432; -> ninf | pnormal | pinf 1433define i1 @oeq_neginfinity_or_oge_smallest_normal(half %x) #0 { 1434; CHECK-LABEL: @oeq_neginfinity_or_oge_smallest_normal( 1435; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772) 1436; CHECK-NEXT: ret i1 [[CLASS]] 1437; 1438 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1439 %cmp.smallest.normal = fcmp oge half %x, 0xH0400 1440 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal 1441 ret i1 %class 1442} 1443 1444; -> false 1445define i1 @oeq_neginfinity_and_oge_smallest_normal(half %x) #0 { 1446; CHECK-LABEL: @oeq_neginfinity_and_oge_smallest_normal( 1447; CHECK-NEXT: ret i1 false 1448; 1449 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1450 %cmp.smallest.normal = fcmp oge half %x, 0xH0400 1451 %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal 1452 ret i1 %class 1453} 1454 1455; -> ord 1456define i1 @oeq_neginfinity_or_ord(half %x) #0 { 1457; CHECK-LABEL: @oeq_neginfinity_or_ord( 1458; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1459; CHECK-NEXT: ret i1 [[CLASS]] 1460; 1461 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1462 %ord = fcmp ord half %x, 0.0 1463 %class = or i1 %oeq.neg.infinity, %ord 1464 ret i1 %class 1465} 1466 1467; -> ninf 1468define i1 @oeq_neginfinity_and_ord(half %x) #0 { 1469; CHECK-LABEL: @oeq_neginfinity_and_ord( 1470; CHECK-NEXT: [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1471; CHECK-NEXT: ret i1 [[OEQ_NEG_INFINITY]] 1472; 1473 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00 1474 %ord = fcmp ord half %x, 0.0 1475 %class = and i1 %oeq.neg.infinity, %ord 1476 ret i1 %class 1477} 1478 1479; can't do anything with this 1480define i1 @une_neginfinity_or_oeq_smallest_normal(half %x) #0 { 1481; CHECK-LABEL: @une_neginfinity_or_oeq_smallest_normal( 1482; CHECK-NEXT: [[UNE_NEG_INFINITY:%.*]] = fcmp une half [[X:%.*]], 0xHFC00 1483; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400 1484; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[UNE_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]] 1485; CHECK-NEXT: ret i1 [[CLASS]] 1486; 1487 %une.neg.infinity = fcmp une half %x, 0xHFC00 1488 %cmp.smallest.normal = fcmp oeq half %x, 0xH0400 1489 %class = or i1 %une.neg.infinity, %cmp.smallest.normal 1490 ret i1 %class 1491} 1492 1493; -> true 1494define i1 @une_neginfinity_or_ord(half %x) #0 { 1495; CHECK-LABEL: @une_neginfinity_or_ord( 1496; CHECK-NEXT: ret i1 true 1497; 1498 %une.neg.infinity = fcmp une half %x, 0xHFC00 1499 %ord = fcmp ord half %x, 0.0 1500 %class = or i1 %une.neg.infinity, %ord 1501 ret i1 %class 1502} 1503 1504; -> ~(nan | ninf) 1505define i1 @une_neginfinity_and_ord(half %x) #0 { 1506; CHECK-LABEL: @une_neginfinity_and_ord( 1507; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xHFC00 1508; CHECK-NEXT: ret i1 [[CLASS]] 1509; 1510 %une.neg.infinity = fcmp une half %x, 0xHFC00 1511 %ord = fcmp ord half %x, 0.0 1512 %class = and i1 %une.neg.infinity, %ord 1513 ret i1 %class 1514} 1515 1516; -> ord 1517define i1 @one_neginfinity_or_olt_smallest_normal(half %x) #0 { 1518; CHECK-LABEL: @one_neginfinity_or_olt_smallest_normal( 1519; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1520; CHECK-NEXT: ret i1 [[CLASS]] 1521; 1522 %one.neg.infinity = fcmp one half %x, 0xHFC00 1523 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1524 %class = or i1 %one.neg.infinity, %cmp.smallest.normal 1525 ret i1 %class 1526} 1527 1528; -> ~(nan|ninf) 1529define i1 @one_neginfinity_and_olt_smallest_normal(half %x) #0 { 1530; CHECK-LABEL: @one_neginfinity_and_olt_smallest_normal( 1531; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 248) 1532; CHECK-NEXT: ret i1 [[CLASS]] 1533; 1534 %one.neg.infinity = fcmp one half %x, 0xHFC00 1535 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1536 %class = and i1 %one.neg.infinity, %cmp.smallest.normal 1537 ret i1 %class 1538} 1539 1540; -> ~ninf 1541define i1 @one_neginfinity_or_uno(half %x) #0 { 1542; CHECK-LABEL: @one_neginfinity_or_uno( 1543; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xHFC00 1544; CHECK-NEXT: ret i1 [[CLASS]] 1545; 1546 %one.neg.infinity = fcmp one half %x, 0xHFC00 1547 %uno = fcmp uno half %x, 0.0 1548 %class = or i1 %one.neg.infinity, %uno 1549 ret i1 %class 1550} 1551 1552; -> ~ninf 1553define i1 @one_neginfinity_and_ord(half %x) #0 { 1554; CHECK-LABEL: @one_neginfinity_and_ord( 1555; CHECK-NEXT: ret i1 false 1556; 1557 %one.neg.infinity = fcmp one half %x, 0xHFC00 1558 %ord = fcmp uno half %x, 0.0 1559 %class = and i1 %one.neg.infinity, %ord 1560 ret i1 %class 1561} 1562 1563; -> pnormal|pinf 1564define i1 @one_neginfinity_and_uge_smallest_normal(half %x) #0 { 1565; CHECK-LABEL: @one_neginfinity_and_uge_smallest_normal( 1566; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768) 1567; CHECK-NEXT: ret i1 [[CLASS]] 1568; 1569 %one.neg.infinity = fcmp one half %x, 0xHFC00 1570 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1571 %class = and i1 %one.neg.infinity, %cmp.smallest.normal 1572 ret i1 %class 1573} 1574 1575; -> ~(pnormal|pinf) 1576define i1 @ueq_neginfinity_or_olt_smallest_normal(half %x) #0 { 1577; CHECK-LABEL: @ueq_neginfinity_or_olt_smallest_normal( 1578; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255) 1579; CHECK-NEXT: ret i1 [[CLASS]] 1580; 1581 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00 1582 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1583 %class = or i1 %ueq.neg.infinity, %cmp.smallest.normal 1584 ret i1 %class 1585} 1586 1587; -> ninf 1588define i1 @ueq_neginfinity_and_olt_smallest_normal(half %x) #0 { 1589; CHECK-LABEL: @ueq_neginfinity_and_olt_smallest_normal( 1590; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1591; CHECK-NEXT: ret i1 [[CLASS]] 1592; 1593 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00 1594 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1595 %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal 1596 ret i1 %class 1597} 1598 1599; -> nan|ninf 1600define i1 @ueq_neginfinity_or_uno(half %x) #0 { 1601; CHECK-LABEL: @ueq_neginfinity_or_uno( 1602; CHECK-NEXT: [[UEQ_NEG_INFINITY:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00 1603; CHECK-NEXT: ret i1 [[UEQ_NEG_INFINITY]] 1604; 1605 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00 1606 %uno = fcmp uno half %x, 0.0 1607 %class = or i1 %ueq.neg.infinity, %uno 1608 ret i1 %class 1609} 1610 1611; -> nan|ninf 1612define i1 @ueq_neginfinity_and_ord(half %x) #0 { 1613; CHECK-LABEL: @ueq_neginfinity_and_ord( 1614; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 1615; CHECK-NEXT: ret i1 [[CLASS]] 1616; 1617 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00 1618 %ord = fcmp uno half %x, 0.0 1619 %class = and i1 %ueq.neg.infinity, %ord 1620 ret i1 %class 1621} 1622 1623; -> uno 1624define i1 @ueq_neginfinity_and_uge_smallest_normal(half %x) #0 { 1625; CHECK-LABEL: @ueq_neginfinity_and_uge_smallest_normal( 1626; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000 1627; CHECK-NEXT: ret i1 [[CLASS]] 1628; 1629 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00 1630 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1631 %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal 1632 ret i1 %class 1633} 1634 1635; -> ord 1636define i1 @fabs_oeq_neginfinity_or_ord(half %x) #0 { 1637; CHECK-LABEL: @fabs_oeq_neginfinity_or_ord( 1638; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1639; CHECK-NEXT: ret i1 [[ORD]] 1640; 1641 %fabs = call half @llvm.fabs.f16(half %x) 1642 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00 1643 %ord = fcmp ord half %x, 0.0 1644 %class = or i1 %fabs.oeq.neg.infinity, %ord 1645 ret i1 %class 1646} 1647 1648; -> true 1649define i1 @fabs_une_neginfinity_or_ord(half %x) #0 { 1650; CHECK-LABEL: @fabs_une_neginfinity_or_ord( 1651; CHECK-NEXT: ret i1 true 1652; 1653 %fabs = call half @llvm.fabs.f16(half %x) 1654 %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00 1655 %ord = fcmp une half %x, 0.0 1656 %class = or i1 %fabs.une.neg.infinity, %ord 1657 ret i1 %class 1658} 1659 1660; -> une 1661define i1 @fabs_une_neginfinity_and_ord(half %x) #0 { 1662; CHECK-LABEL: @fabs_une_neginfinity_and_ord( 1663; CHECK-NEXT: [[ORD:%.*]] = fcmp une half [[X:%.*]], 0xH0000 1664; CHECK-NEXT: ret i1 [[ORD]] 1665; 1666 %fabs = call half @llvm.fabs.f16(half %x) 1667 %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00 1668 %ord = fcmp une half %x, 0.0 1669 %class = and i1 %fabs.une.neg.infinity, %ord 1670 ret i1 %class 1671} 1672 1673; -> false 1674define i1 @fabs_oeq_neginfinity_and_uge_smallest_normal(half %x) #0 { 1675; CHECK-LABEL: @fabs_oeq_neginfinity_and_uge_smallest_normal( 1676; CHECK-NEXT: ret i1 false 1677; 1678 %fabs = call half @llvm.fabs.f16(half %x) 1679 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00 1680 %cmp.smallest.normal = fcmp oeq half %x, 0xH0400 1681 %class = and i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal 1682 ret i1 %class 1683} 1684 1685; -> false 1686define i1 @fabs_oeq_neginfinity_or_uge_smallest_normal(half %x) #0 { 1687; CHECK-LABEL: @fabs_oeq_neginfinity_or_uge_smallest_normal( 1688; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X:%.*]], 0xH0400 1689; CHECK-NEXT: ret i1 [[CMP_SMALLEST_NORMAL]] 1690; 1691 %fabs = call half @llvm.fabs.f16(half %x) 1692 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00 1693 %cmp.smallest.normal = fcmp oeq half %x, 0xH0400 1694 %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal 1695 ret i1 %class 1696} 1697 1698;- > ord 1699define i1 @fabs_oeq_neginfinity_and_ord(half %x) #0 { 1700; CHECK-LABEL: @fabs_oeq_neginfinity_and_ord( 1701; CHECK-NEXT: ret i1 false 1702; 1703 %fabs = call half @llvm.fabs.f16(half %x) 1704 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00 1705 %ord = fcmp ord half %x, 0.0 1706 %class = and i1 %fabs.oeq.neg.infinity, %ord 1707 ret i1 %class 1708} 1709 1710; -> false 1711define i1 @fabs_ueq_neginfinity_and_olt_smallest_normal(half %x) #0 { ; WRONG 1712; CHECK-LABEL: @fabs_ueq_neginfinity_and_olt_smallest_normal( 1713; CHECK-NEXT: ret i1 false 1714; 1715 %fabs = call half @llvm.fabs.f16(half %x) 1716 %fabs.ueq.neg.infinity = fcmp ueq half %fabs, 0xHFC00 1717 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1718 %class = and i1 %fabs.ueq.neg.infinity, %cmp.smallest.normal 1719 ret i1 %class 1720} 1721 1722; -> pinf|pnormal 1723define i1 @fabs_one_neginfinity_and_uge_smallest_normal(half %x) #0 { 1724; CHECK-LABEL: @fabs_one_neginfinity_and_uge_smallest_normal( 1725; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768) 1726; CHECK-NEXT: ret i1 [[CLASS]] 1727; 1728 %fabs = call half @llvm.fabs.f16(half %x) 1729 %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00 1730 %cmp.smallest.normal = fcmp uge half %x, 0xH0400 1731 %class = and i1 %fabs.one.neg.infinity, %cmp.smallest.normal 1732 ret i1 %class 1733} 1734 1735; -> ord 1736define i1 @fabs_one_neginfinity_or_olt_smallest_normal(half %x) #0 { 1737; CHECK-LABEL: @fabs_one_neginfinity_or_olt_smallest_normal( 1738; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1739; CHECK-NEXT: ret i1 [[CLASS]] 1740; 1741 %fabs = call half @llvm.fabs.f16(half %x) 1742 %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00 1743 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 1744 %class = or i1 %fabs.one.neg.infinity, %cmp.smallest.normal 1745 ret i1 %class 1746} 1747 1748; -> ~(zero|subnormal) 1749define i1 @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(half %x) #0 { 1750; CHECK-LABEL: @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal( 1751; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783) 1752; CHECK-NEXT: ret i1 [[CLASS]] 1753; 1754 %fabs = call half @llvm.fabs.f16(half %x) 1755 %fabs.oeq.neg.infinity = fcmp ueq half %fabs, 0xHFC00 1756 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400 1757 %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal 1758 ret i1 %class 1759} 1760 1761; -------------------------------------------------------------------- 1762; Test denormal mode handling with x == 0 1763; -------------------------------------------------------------------- 1764 1765; Base pattern !isfinite(x) || x == 0.0, with input denormals flushed to 0 1766define i1 @not_isfinite_or_zero_f16_daz(half %x) #1 { 1767; CHECK-LABEL: @not_isfinite_or_zero_f16_daz( 1768; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1769; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 1770; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 1771; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 1772; CHECK-NEXT: ret i1 [[CLASS]] 1773; 1774 %fabs = call half @llvm.fabs.f16(half %x) 1775 %cmpinf = fcmp ueq half %fabs, 0xH7C00 1776 %cmpzero = fcmp oeq half %x, 0xH0000 1777 %class = or i1 %cmpzero, %cmpinf 1778 ret i1 %class 1779} 1780 1781define <2 x i1> @not_isfinite_or_zero_v2f16_daz(<2 x half> %x) #1 { 1782; CHECK-LABEL: @not_isfinite_or_zero_v2f16_daz( 1783; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) 1784; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00) 1785; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer 1786; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]] 1787; CHECK-NEXT: ret <2 x i1> [[CLASS]] 1788; 1789 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 1790 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 1791 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer 1792 %class = or <2 x i1> %cmpzero, %cmpinf 1793 ret <2 x i1> %class 1794} 1795 1796; Base pattern !isfinite(x) || x == 0.0, with unknown input denormal treatment 1797define i1 @not_isfinite_or_zero_f16_dynamic(half %x) #2 { 1798; CHECK-LABEL: @not_isfinite_or_zero_f16_dynamic( 1799; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1800; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00 1801; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 1802; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]] 1803; CHECK-NEXT: ret i1 [[CLASS]] 1804; 1805 %fabs = call half @llvm.fabs.f16(half %x) 1806 %cmpinf = fcmp ueq half %fabs, 0xH7C00 1807 %cmpzero = fcmp oeq half %x, 0xH0000 1808 %class = or i1 %cmpzero, %cmpinf 1809 ret i1 %class 1810} 1811 1812define <2 x i1> @not_isfinite_or_zero_v2f16_dynamic(<2 x half> %x) #2 { 1813; CHECK-LABEL: @not_isfinite_or_zero_v2f16_dynamic( 1814; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) 1815; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00) 1816; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer 1817; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]] 1818; CHECK-NEXT: ret <2 x i1> [[CLASS]] 1819; 1820 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) 1821 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00> 1822 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer 1823 %class = or <2 x i1> %cmpzero, %cmpinf 1824 ret <2 x i1> %class 1825} 1826 1827define i1 @not_zero_and_subnormal_daz(half %x) #1 { 1828; CHECK-LABEL: @not_zero_and_subnormal_daz( 1829; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 1830; CHECK-NEXT: ret i1 [[OR]] 1831; 1832 %fabs = call half @llvm.fabs.f16(half %x) 1833 %cmp.zero = fcmp one half %fabs, 0.0 1834 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 1835 %or = or i1 %cmp.smallest.normal, %cmp.zero 1836 ret i1 %or 1837} 1838 1839define i1 @not_zero_and_subnormal_dynamic(half %x) #2 { 1840; CHECK-LABEL: @not_zero_and_subnormal_dynamic( 1841; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1842; CHECK-NEXT: [[CMP_ZERO:%.*]] = fcmp one half [[X]], 0xH0000 1843; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 1844; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMP_ZERO]] 1845; CHECK-NEXT: ret i1 [[OR]] 1846; 1847 %fabs = call half @llvm.fabs.f16(half %x) 1848 %cmp.zero = fcmp one half %fabs, 0.0 1849 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400 1850 %or = or i1 %cmp.smallest.normal, %cmp.zero 1851 ret i1 %or 1852} 1853 1854; TODO: This could fold to just fcmp olt half %fabs, 0xH0400 1855define i1 @subnormal_or_zero_ieee(half %x) #0 { 1856; CHECK-LABEL: @subnormal_or_zero_ieee( 1857; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) 1858; CHECK-NEXT: ret i1 [[AND]] 1859; 1860 %fabs = call half @llvm.fabs.f16(half %x) 1861 %is.subnormal = fcmp olt half %fabs, 0xH0400 1862 %is.zero = fcmp oeq half %x, 0xH0000 1863 %and = or i1 %is.subnormal, %is.zero 1864 ret i1 %and 1865} 1866 1867define i1 @subnormal_or_zero_daz(half %x) #1 { 1868; CHECK-LABEL: @subnormal_or_zero_daz( 1869; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 1870; CHECK-NEXT: ret i1 [[AND]] 1871; 1872 %fabs = call half @llvm.fabs.f16(half %x) 1873 %is.subnormal = fcmp olt half %fabs, 0xH0400 1874 %is.zero = fcmp oeq half %x, 0xH0000 1875 %and = or i1 %is.subnormal, %is.zero 1876 ret i1 %and 1877} 1878 1879define i1 @subnormal_or_zero_dynamic(half %x) #2 { 1880; CHECK-LABEL: @subnormal_or_zero_dynamic( 1881; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) 1882; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 1883; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH0000 1884; CHECK-NEXT: [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]] 1885; CHECK-NEXT: ret i1 [[AND]] 1886; 1887 %fabs = call half @llvm.fabs.f16(half %x) 1888 %is.subnormal = fcmp olt half %fabs, 0xH0400 1889 %is.zero = fcmp oeq half %x, 0xH0000 1890 %and = or i1 %is.subnormal, %is.zero 1891 ret i1 %and 1892} 1893 1894define i1 @issubnormal_or_inf_nnan_logical_select(half %x) { 1895; CHECK-LABEL: @issubnormal_or_inf_nnan_logical_select( 1896; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756) 1897; CHECK-NEXT: ret i1 [[CLASS]] 1898; 1899 %fabs = call nnan half @llvm.fabs.f16(half %x) 1900 %cmpinf = fcmp nnan oeq half %fabs, 0xH7C00 1901 %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400 1902 %class = select i1 %cmpinf, i1 true, i1 %cmp.smallest.normal 1903 ret i1 %class 1904} 1905 1906define i1 @issubnormal_and_ninf_nnan_logical_select(half %x) { 1907; CHECK-LABEL: @issubnormal_and_ninf_nnan_logical_select( 1908; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) 1909; CHECK-NEXT: ret i1 [[CLASS]] 1910; 1911 %fabs = call nnan half @llvm.fabs.f16(half %x) 1912 %cmpinf = fcmp nnan one half %fabs, 0xH7C00 1913 %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400 1914 %class = select i1 %cmpinf, i1 %cmp.smallest.normal, i1 false 1915 ret i1 %class 1916} 1917 1918define i1 @fcmp_ueq_neginf_or_oge_zero_f16(half %x) { 1919; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16( 1920; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 999) 1921; CHECK-NEXT: ret i1 [[CLASS]] 1922; 1923 %cmpinf = fcmp ueq half %x, 0xHFC00 1924 %cmp.oge.zero = fcmp oge half %x, 0xH0000 1925 %class = or i1 %cmp.oge.zero, %cmpinf 1926 ret i1 %class 1927} 1928 1929define i1 @fcmp_oeq_neginf_or_oge_zero_f16(half %x) { 1930; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16( 1931; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 996) 1932; CHECK-NEXT: ret i1 [[CLASS]] 1933; 1934 %cmpinf = fcmp oeq half %x, 0xHFC00 1935 %cmp.oge.zero = fcmp oge half %x, 0xH0000 1936 %class = or i1 %cmp.oge.zero, %cmpinf 1937 ret i1 %class 1938} 1939 1940define i1 @fcmp_ueq_neginf_or_oge_zero_f16_daz(half %x) #1 { 1941; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16_daz( 1942; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00 1943; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000 1944; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]] 1945; CHECK-NEXT: ret i1 [[CLASS]] 1946; 1947 %cmpinf = fcmp ueq half %x, 0xHFC00 1948 %cmp.oge.zero = fcmp oge half %x, 0xH0000 1949 %class = or i1 %cmp.oge.zero, %cmpinf 1950 ret i1 %class 1951} 1952 1953define i1 @fcmp_oeq_neginf_or_oge_zero_f16_daz(half %x) #1 { 1954; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16_daz( 1955; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 1956; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000 1957; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]] 1958; CHECK-NEXT: ret i1 [[CLASS]] 1959; 1960 %cmpinf = fcmp oeq half %x, 0xHFC00 1961 %cmp.oge.zero = fcmp oge half %x, 0xH0000 1962 %class = or i1 %cmp.oge.zero, %cmpinf 1963 ret i1 %class 1964} 1965 1966define i1 @fcmp_oeq_neginf_or_ogt_zero_f16(half %x) { 1967; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16( 1968; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 900) 1969; CHECK-NEXT: ret i1 [[CLASS]] 1970; 1971 %cmpinf = fcmp oeq half %x, 0xHFC00 1972 %cmp.ogt.zero = fcmp ogt half %x, 0xH0000 1973 %class = or i1 %cmp.ogt.zero, %cmpinf 1974 ret i1 %class 1975} 1976 1977define i1 @fcmp_ueq_neginf_or_ogt_zero_f16(half %x) { 1978; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16( 1979; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903) 1980; CHECK-NEXT: ret i1 [[CLASS]] 1981; 1982 %cmpinf = fcmp ueq half %x, 0xHFC00 1983 %cmp.ogt.zero = fcmp ogt half %x, 0xH0000 1984 %class = or i1 %cmp.ogt.zero, %cmpinf 1985 ret i1 %class 1986} 1987 1988define i1 @fcmp_ueq_neginf_or_ogt_zero_f16_daz(half %x) #1 { 1989; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16_daz( 1990; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00 1991; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000 1992; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]] 1993; CHECK-NEXT: ret i1 [[CLASS]] 1994; 1995 %cmpinf = fcmp ueq half %x, 0xHFC00 1996 %cmp.ogt.zero = fcmp ogt half %x, 0xH0000 1997 %class = or i1 %cmp.ogt.zero, %cmpinf 1998 ret i1 %class 1999} 2000 2001define i1 @fcmp_oeq_neginf_or_ogt_zero_f16_daz(half %x) #1 { 2002; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16_daz( 2003; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 2004; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000 2005; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]] 2006; CHECK-NEXT: ret i1 [[CLASS]] 2007; 2008 %cmpinf = fcmp oeq half %x, 0xHFC00 2009 %cmp.ogt.zero = fcmp ogt half %x, 0xH0000 2010 %class = or i1 %cmp.ogt.zero, %cmpinf 2011 ret i1 %class 2012} 2013 2014define i1 @fcmp_oeq_neginf_or_ugt_zero_f16(half %x) { 2015; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16( 2016; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903) 2017; CHECK-NEXT: ret i1 [[CLASS]] 2018; 2019 %cmpinf = fcmp oeq half %x, 0xHFC00 2020 %cmp.ugt.zero = fcmp ugt half %x, 0xH0000 2021 %class = or i1 %cmp.ugt.zero, %cmpinf 2022 ret i1 %class 2023} 2024 2025define i1 @fcmp_ueq_neginf_or_ugt_zero_f16_daz(half %x) #1 { 2026; CHECK-LABEL: @fcmp_ueq_neginf_or_ugt_zero_f16_daz( 2027; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00 2028; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000 2029; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]] 2030; CHECK-NEXT: ret i1 [[CLASS]] 2031; 2032 %cmpinf = fcmp ueq half %x, 0xHFC00 2033 %cmp.ugt.zero = fcmp ugt half %x, 0xH0000 2034 %class = or i1 %cmp.ugt.zero, %cmpinf 2035 ret i1 %class 2036} 2037 2038define i1 @fcmp_oeq_neginf_or_ugt_zero_f16_daz(half %x) #1 { 2039; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16_daz( 2040; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00 2041; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000 2042; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]] 2043; CHECK-NEXT: ret i1 [[CLASS]] 2044; 2045 %cmpinf = fcmp oeq half %x, 0xHFC00 2046 %cmp.ugt.zero = fcmp ugt half %x, 0xH0000 2047 %class = or i1 %cmp.ugt.zero, %cmpinf 2048 ret i1 %class 2049} 2050 2051define i1 @fcmp_ueq_posinf_or_ole_zero_f16(half %x) { 2052; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16( 2053; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639) 2054; CHECK-NEXT: ret i1 [[CLASS]] 2055; 2056 %cmpinf = fcmp ueq half %x, 0xH7C00 2057 %cmp.ole.zero = fcmp ole half %x, 0xH0000 2058 %class = or i1 %cmp.ole.zero, %cmpinf 2059 ret i1 %class 2060} 2061 2062define i1 @fcmp_oeq_posinf_or_ole_zero_f16(half %x) { 2063; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16( 2064; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 636) 2065; CHECK-NEXT: ret i1 [[CLASS]] 2066; 2067 %cmpinf = fcmp oeq half %x, 0xH7C00 2068 %cmp.ole.zero = fcmp ole half %x, 0xH0000 2069 %class = or i1 %cmp.ole.zero, %cmpinf 2070 ret i1 %class 2071} 2072 2073define i1 @fcmp_ueq_posinf_or_ole_zero_f16_daz(half %x) #1 { 2074; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16_daz( 2075; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 2076; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000 2077; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]] 2078; CHECK-NEXT: ret i1 [[CLASS]] 2079; 2080 %cmpinf = fcmp ueq half %x, 0xH7C00 2081 %cmp.ole.zero = fcmp ole half %x, 0xH0000 2082 %class = or i1 %cmp.ole.zero, %cmpinf 2083 ret i1 %class 2084} 2085 2086define i1 @fcmp_oeq_posinf_or_ole_zero_f16_daz(half %x) #1 { 2087; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16_daz( 2088; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 2089; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000 2090; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]] 2091; CHECK-NEXT: ret i1 [[CLASS]] 2092; 2093 %cmpinf = fcmp oeq half %x, 0xH7C00 2094 %cmp.ole.zero = fcmp ole half %x, 0xH0000 2095 %class = or i1 %cmp.ole.zero, %cmpinf 2096 ret i1 %class 2097} 2098 2099define i1 @fcmp_oeq_posinf_or_olt_zero_f16(half %x) { 2100; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16( 2101; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 540) 2102; CHECK-NEXT: ret i1 [[CLASS]] 2103; 2104 %cmpinf = fcmp oeq half %x, 0xH7C00 2105 %cmp.olt.zero = fcmp olt half %x, 0xH0000 2106 %class = or i1 %cmp.olt.zero, %cmpinf 2107 ret i1 %class 2108} 2109 2110define i1 @fcmp_oeq_posinf_or_olt_zero_f16_daz(half %x) #1 { 2111; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16_daz( 2112; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 2113; CHECK-NEXT: [[CMP_OLT_ZERO:%.*]] = fcmp olt half [[X]], 0xH0000 2114; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLT_ZERO]], [[CMPINF]] 2115; CHECK-NEXT: ret i1 [[CLASS]] 2116; 2117 %cmpinf = fcmp oeq half %x, 0xH7C00 2118 %cmp.olt.zero = fcmp olt half %x, 0xH0000 2119 %class = or i1 %cmp.olt.zero, %cmpinf 2120 ret i1 %class 2121} 2122 2123define i1 @fcmp_ueq_posinf_or_ult_zero_f16(half %x) { 2124; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16( 2125; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543) 2126; CHECK-NEXT: ret i1 [[CLASS]] 2127; 2128 %cmpinf = fcmp ueq half %x, 0xH7C00 2129 %cmp.ult.zero = fcmp ult half %x, 0xH0000 2130 %class = or i1 %cmp.ult.zero, %cmpinf 2131 ret i1 %class 2132} 2133 2134define i1 @fcmp_oeq_posinf_or_ult_zero_f16(half %x) { 2135; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16( 2136; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543) 2137; CHECK-NEXT: ret i1 [[CLASS]] 2138; 2139 %cmpinf = fcmp oeq half %x, 0xH7C00 2140 %cmp.ult.zero = fcmp ult half %x, 0xH0000 2141 %class = or i1 %cmp.ult.zero, %cmpinf 2142 ret i1 %class 2143} 2144 2145define i1 @fcmp_ueq_posinf_or_ult_zero_f16_daz(half %x) #1 { 2146; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16_daz( 2147; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 2148; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000 2149; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]] 2150; CHECK-NEXT: ret i1 [[CLASS]] 2151; 2152 %cmpinf = fcmp ueq half %x, 0xH7C00 2153 %cmp.ult.zero = fcmp ult half %x, 0xH0000 2154 %class = or i1 %cmp.ult.zero, %cmpinf 2155 ret i1 %class 2156} 2157 2158define i1 @fcmp_oeq_posinf_or_ult_zero_f16_daz(half %x) #1 { 2159; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16_daz( 2160; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 2161; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000 2162; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]] 2163; CHECK-NEXT: ret i1 [[CLASS]] 2164; 2165 %cmpinf = fcmp oeq half %x, 0xH7C00 2166 %cmp.ult.zero = fcmp ult half %x, 0xH0000 2167 %class = or i1 %cmp.ult.zero, %cmpinf 2168 ret i1 %class 2169} 2170 2171define i1 @fcmp_ueq_posinf_or_ule_zero_f16(half %x) { 2172; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16( 2173; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639) 2174; CHECK-NEXT: ret i1 [[CLASS]] 2175; 2176 %cmpinf = fcmp ueq half %x, 0xH7C00 2177 %cmp.ule.zero = fcmp ule half %x, 0xH0000 2178 %class = or i1 %cmp.ule.zero, %cmpinf 2179 ret i1 %class 2180} 2181 2182define i1 @fcmp_ueq_posinf_or_ule_zero_f16_daz(half %x) #1 { 2183; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16_daz( 2184; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00 2185; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000 2186; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]] 2187; CHECK-NEXT: ret i1 [[CLASS]] 2188; 2189 %cmpinf = fcmp ueq half %x, 0xH7C00 2190 %cmp.ule.zero = fcmp ule half %x, 0xH0000 2191 %class = or i1 %cmp.ule.zero, %cmpinf 2192 ret i1 %class 2193} 2194 2195define i1 @fcmp_oeq_posinf_or_ule_zero_f16_daz(half %x) #1 { 2196; CHECK-LABEL: @fcmp_oeq_posinf_or_ule_zero_f16_daz( 2197; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 2198; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000 2199; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]] 2200; CHECK-NEXT: ret i1 [[CLASS]] 2201; 2202 %cmpinf = fcmp oeq half %x, 0xH7C00 2203 %cmp.ule.zero = fcmp ule half %x, 0xH0000 2204 %class = or i1 %cmp.ule.zero, %cmpinf 2205 ret i1 %class 2206} 2207 2208define i1 @fcmp_ueq_posinf_or_olt_zero_f16(half %x) { 2209; CHECK-LABEL: @fcmp_ueq_posinf_or_olt_zero_f16( 2210; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543) 2211; CHECK-NEXT: ret i1 [[CLASS]] 2212; 2213 %cmpinf = fcmp ueq half %x, 0xH7C00 2214 %cmp.olt.zero = fcmp olt half %x, 0xH0000 2215 %class = or i1 %cmp.olt.zero, %cmpinf 2216 ret i1 %class 2217} 2218 2219declare half @llvm.fabs.f16(half) #0 2220declare half @llvm.canonicalize.f16(half) #0 2221declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0 2222 2223attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } 2224attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" } 2225attributes #2 = { "denormal-fp-math"="ieee,dynamic" } 2226