1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2 2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC 4 5declare nofpclass(nan) float @ret_nofpclass_nan() 6declare [2 x [3 x float]] @ret_array() 7declare float @extern() 8declare float @extern.f32(float) 9declare void @extern.use(float) 10declare void @extern.use.array([2 x [3 x float]]) 11declare void @llvm.assume(i1 noundef) 12declare void @unknown() 13declare half @llvm.fabs.f16(half) 14declare float @llvm.fabs.f32(float) 15declare void @extern.use.f16(half) 16declare i1 @llvm.is.fpclass.f32(float, i32 immarg) 17declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) 18declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata) 19declare float @llvm.arithmetic.fence.f32(float) 20 21define float @returned_0() { 22; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @returned_0() { 23; CHECK-NEXT: call void @unknown() 24; CHECK-NEXT: ret float 0.000000e+00 25; 26 call void @unknown() 27 ret float 0.0 28} 29 30define float @returned_neg0() { 31; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @returned_neg0() { 32; CHECK-NEXT: call void @unknown() 33; CHECK-NEXT: ret float -0.000000e+00 34; 35 call void @unknown() 36 ret float -0.0 37} 38 39define float @returned_undef() { 40; CHECK-LABEL: define nofpclass(all) float @returned_undef() { 41; CHECK-NEXT: call void @unknown() 42; CHECK-NEXT: ret float undef 43; 44 call void @unknown() 45 ret float undef 46} 47 48define float @returned_poison() { 49; CHECK-LABEL: define nofpclass(all) float @returned_poison() { 50; CHECK-NEXT: call void @unknown() 51; CHECK-NEXT: ret float poison 52; 53 call void @unknown() 54 ret float poison 55} 56 57; Know nothing 58define float @returned_freeze_poison() { 59; CHECK-LABEL: define noundef float @returned_freeze_poison() { 60; CHECK-NEXT: call void @unknown() 61; CHECK-NEXT: [[FREEZE_POISON:%.*]] = freeze float poison 62; CHECK-NEXT: ret float [[FREEZE_POISON]] 63; 64 call void @unknown() 65 %freeze.poison = freeze float poison 66 ret float %freeze.poison 67} 68 69define double @returned_snan() { 70; CHECK-LABEL: define noundef nofpclass(qnan inf zero sub norm) double @returned_snan() { 71; CHECK-NEXT: call void @unknown() 72; CHECK-NEXT: ret double 0x7FF0000000000001 73; 74 call void @unknown() 75 ret double 0x7FF0000000000001 76} 77 78define double @returned_qnan() { 79; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) double @returned_qnan() { 80; CHECK-NEXT: call void @unknown() 81; CHECK-NEXT: ret double 0x7FF8000000000000 82; 83 call void @unknown() 84 ret double 0x7FF8000000000000 85} 86 87define <2 x double> @returned_zero_vector() { 88; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <2 x double> @returned_zero_vector() { 89; CHECK-NEXT: call void @unknown() 90; CHECK-NEXT: ret <2 x double> zeroinitializer 91; 92 call void @unknown() 93 ret <2 x double> zeroinitializer 94} 95 96define <2 x double> @returned_negzero_vector() { 97; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) <2 x double> @returned_negzero_vector() { 98; CHECK-NEXT: call void @unknown() 99; CHECK-NEXT: ret <2 x double> splat (double -0.000000e+00) 100; 101 call void @unknown() 102 ret <2 x double> <double -0.0, double -0.0> 103} 104 105; Test a vector element that's a constant but not ConstantFP. 106define <2 x double> @returned_strange_constant_vector_elt() { 107; CHECK-LABEL: define <2 x double> @returned_strange_constant_vector_elt() { 108; CHECK-NEXT: call void @unknown() 109; CHECK-NEXT: ret <2 x double> <double -0.000000e+00, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)> 110; 111 call void @unknown() 112 ret <2 x double> <double -0.0, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)> 113} 114 115; Test a vector element that's undef 116define <3 x double> @returned_undef_constant_vector_elt() { 117; CHECK-LABEL: define <3 x double> @returned_undef_constant_vector_elt() { 118; CHECK-NEXT: call void @unknown() 119; CHECK-NEXT: ret <3 x double> <double -0.000000e+00, double 0.000000e+00, double undef> 120; 121 call void @unknown() 122 ret <3 x double> <double -0.0, double 0.0, double undef> 123} 124 125; Test a vector element that's poison 126define <3 x double> @returned_poison_constant_vector_elt() { 127; CHECK-LABEL: define nofpclass(nan inf sub norm) <3 x double> @returned_poison_constant_vector_elt() { 128; CHECK-NEXT: call void @unknown() 129; CHECK-NEXT: ret <3 x double> <double -0.000000e+00, double 0.000000e+00, double poison> 130; 131 call void @unknown() 132 ret <3 x double> <double -0.0, double 0.0, double poison> 133} 134 135define <2 x double> @returned_qnan_zero_vector() { 136; CHECK-LABEL: define noundef nofpclass(snan inf nzero sub norm) <2 x double> @returned_qnan_zero_vector() { 137; CHECK-NEXT: call void @unknown() 138; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0.000000e+00> 139; 140 call void @unknown() 141 ret <2 x double> <double 0x7FF8000000000000, double 0.0> 142} 143 144; Return a float trivially nofpclass(nan) (call return attribute) 145define float @return_nofpclass_nan_decl_return() { 146; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_decl_return() { 147; CHECK-NEXT: [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan() 148; CHECK-NEXT: ret float [[RET]] 149; 150 %ret = call float @ret_nofpclass_nan() 151 ret float %ret 152} 153 154; Return a float trivially nofpclass(nan) (argument attribute) 155define float @return_nofpclass_nan_arg(float returned nofpclass(nan) %p) { 156; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 157; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_arg 158; CHECK-SAME: (float returned nofpclass(nan) [[P:%.*]]) #[[ATTR3:[0-9]+]] { 159; CHECK-NEXT: ret float [[P]] 160; 161 ret float %p 162} 163 164define [2 x [3 x float]] @return_nofpclass_inf_ret_array() { 165; CHECK-LABEL: define nofpclass(inf) [2 x [3 x float]] @return_nofpclass_inf_ret_array() { 166; CHECK-NEXT: [[RET:%.*]] = call nofpclass(inf) [2 x [3 x float]] @ret_array() 167; CHECK-NEXT: ret [2 x [3 x float]] [[RET]] 168; 169 %ret = call nofpclass(inf) [2 x [3 x float]] @ret_array() 170 ret [2 x [3 x float]] %ret 171} 172 173define float @returned_nnan_fadd(float %arg0, float %arg1) { 174; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 175; CHECK-LABEL: define nofpclass(nan) float @returned_nnan_fadd 176; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] { 177; CHECK-NEXT: [[FADD:%.*]] = fadd nnan float [[ARG0]], [[ARG1]] 178; CHECK-NEXT: ret float [[FADD]] 179; 180 %fadd = fadd nnan float %arg0, %arg1 181 ret float %fadd 182} 183 184define float @return_nofpclass_nan_callsite() { 185; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_callsite() { 186; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @extern() 187; CHECK-NEXT: ret float [[CALL]] 188; 189 %call = call nofpclass(nan) float @extern() 190 ret float %call 191} 192 193; Can union the return classes 194define nofpclass(inf) float @return_ninf_nofpclass_nan_callsite() { 195; CHECK-LABEL: define nofpclass(nan inf) float @return_ninf_nofpclass_nan_callsite() { 196; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @extern() 197; CHECK-NEXT: ret float [[CALL]] 198; 199 %call = call nofpclass(nan) float @extern() 200 ret float %call 201} 202 203define void @arg_used_by_nofpclass_nan_callsite(float %arg) { 204; CHECK-LABEL: define void @arg_used_by_nofpclass_nan_callsite 205; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) { 206; CHECK-NEXT: call void @extern.use(float nofpclass(nan) [[ARG]]) 207; CHECK-NEXT: ret void 208; 209 call void @extern.use(float nofpclass(nan) %arg) 210 ret void 211} 212 213; Callsite can union the incoming and outgoing 214define void @ninf_arg_used_by_nofpclass_nan_callsite(float nofpclass(inf) %arg) { 215; CHECK-LABEL: define void @ninf_arg_used_by_nofpclass_nan_callsite 216; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) { 217; CHECK-NEXT: call void @extern.use(float nofpclass(nan inf) [[ARG]]) 218; CHECK-NEXT: ret void 219; 220 call void @extern.use(float nofpclass(nan) %arg) 221 ret void 222} 223 224define void @ninf_arg_used_by_callsite_array([2 x [3 x float]] nofpclass(inf) %arg) { 225; CHECK-LABEL: define void @ninf_arg_used_by_callsite_array 226; CHECK-SAME: ([2 x [3 x float]] nofpclass(inf) [[ARG:%.*]]) { 227; CHECK-NEXT: call void @extern.use.array([2 x [3 x float]] nofpclass(inf) [[ARG]]) 228; CHECK-NEXT: ret void 229; 230 call void @extern.use.array([2 x [3 x float]] %arg) 231 ret void 232} 233 234define void @nofpclass_call_use_after_unannotated_use(float %arg) { 235; CHECK-LABEL: define void @nofpclass_call_use_after_unannotated_use 236; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) { 237; CHECK-NEXT: call void @extern(float nofpclass(nan inf) [[ARG]]) #[[ATTR17:[0-9]+]] 238; CHECK-NEXT: call void @extern(float nofpclass(nan inf) [[ARG]]) 239; CHECK-NEXT: ret void 240; 241 call void @extern(float %arg) willreturn nounwind ; < annotate this use 242 call void @extern(float nofpclass(nan inf) %arg) 243 ret void 244} 245 246define float @mutually_recursive0(float %arg) { 247; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 248; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive0 249; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { 250; TUNIT-NEXT: ret float undef 251; 252; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 253; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive0 254; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] { 255; CGSCC-NEXT: ret float undef 256; 257 %call = call float @mutually_recursive1(float %arg) 258 ret float %call 259} 260 261define float @mutually_recursive1(float %arg) { 262; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 263; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive1 264; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4]] { 265; TUNIT-NEXT: ret float undef 266; 267; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 268; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive1 269; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] { 270; CGSCC-NEXT: ret float undef 271; 272 %call = call float @mutually_recursive0(float %arg) 273 ret float %call 274} 275 276define float @recursive_phi(ptr %ptr) { 277; CHECK-LABEL: define nofpclass(nan) float @recursive_phi 278; CHECK-SAME: (ptr nofree [[PTR:%.*]]) { 279; CHECK-NEXT: entry: 280; CHECK-NEXT: [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan() 281; CHECK-NEXT: br label [[LOOP:%.*]] 282; CHECK: loop: 283; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[RET]], [[ENTRY:%.*]] ], [ [[RET]], [[LOOP]] ] 284; CHECK-NEXT: [[COND:%.*]] = load volatile i1, ptr [[PTR]], align 1 285; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 286; CHECK: exit: 287; CHECK-NEXT: ret float [[RET]] 288; 289entry: 290 %ret = call float @ret_nofpclass_nan() 291 br label %loop 292 293loop: 294 %phi = phi float [%ret, %entry], [%phi, %loop] 295 %cond = load volatile i1, ptr %ptr 296 br i1 %cond, label %loop, label %exit 297 298exit: 299 ret float %phi 300} 301 302; Should be able to infer nofpclass(nan) return 303define float @fcmp_uno_check(float %arg) local_unnamed_addr { 304; CHECK-LABEL: define float @fcmp_uno_check 305; CHECK-SAME: (float [[ARG:%.*]]) local_unnamed_addr { 306; CHECK-NEXT: entry: 307; CHECK-NEXT: [[ISNAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00 308; CHECK-NEXT: br i1 [[ISNAN]], label [[BB0:%.*]], label [[BB1:%.*]] 309; CHECK: bb0: 310; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan() 311; CHECK-NEXT: br label [[BB1]] 312; CHECK: bb1: 313; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[CALL]], [[BB0]] ], [ [[ARG]], [[ENTRY:%.*]] ] 314; CHECK-NEXT: ret float [[PHI]] 315; 316entry: 317 %isnan = fcmp uno float %arg, 0.0 318 br i1 %isnan, label %bb0, label %bb1 319 320bb0: 321 %call = call float @ret_nofpclass_nan() 322 br label %bb1 323 324bb1: 325 %phi = phi float [ %call, %bb0 ], [ %arg, %entry ] 326 ret float %phi 327} 328 329; Should be able to infer nofpclass(nan) on %arg use 330define void @fcmp_ord_guard_callsite_arg(float %arg) { 331; CHECK-LABEL: define void @fcmp_ord_guard_callsite_arg 332; CHECK-SAME: (float [[ARG:%.*]]) { 333; CHECK-NEXT: entry: 334; CHECK-NEXT: [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00 335; CHECK-NEXT: br i1 [[IS_NOT_NAN]], label [[BB0:%.*]], label [[BB1:%.*]] 336; CHECK: bb0: 337; CHECK-NEXT: call void @extern.use(float [[ARG]]) 338; CHECK-NEXT: br label [[BB1]] 339; CHECK: bb1: 340; CHECK-NEXT: ret void 341; 342entry: 343 %is.not.nan = fcmp ord float %arg, 0.0 344 br i1 %is.not.nan, label %bb0, label %bb1 345 346bb0: 347 call void @extern.use(float %arg) 348 br label %bb1 349 350bb1: 351 ret void 352} 353 354; Should be able to infer nofpclass on both %arg uses 355define float @fcmp_ord_assume_callsite_arg_return(float %arg) { 356; CHECK-LABEL: define float @fcmp_ord_assume_callsite_arg_return 357; CHECK-SAME: (float returned [[ARG:%.*]]) { 358; CHECK-NEXT: entry: 359; CHECK-NEXT: [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00 360; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_NOT_NAN]]) #[[ATTR18:[0-9]+]] 361; CHECK-NEXT: call void @extern.use(float [[ARG]]) 362; CHECK-NEXT: ret float [[ARG]] 363; 364entry: 365 %is.not.nan = fcmp ord float %arg, 0.0 366 call void @llvm.assume(i1 %is.not.nan) 367 call void @extern.use(float %arg) 368 ret float %arg 369} 370 371define internal float @returned_dead() { 372; CHECK-LABEL: define internal nofpclass(nan inf nzero sub norm) float @returned_dead() { 373; CHECK-NEXT: call void @unknown() 374; CHECK-NEXT: ret float undef 375; 376 call void @unknown() 377 ret float 0.0 378} 379 380define void @returned_dead_caller() { 381; CHECK-LABEL: define void @returned_dead_caller() { 382; CHECK-NEXT: [[TMP1:%.*]] = call float @returned_dead() 383; CHECK-NEXT: ret void 384; 385 call float @returned_dead() 386 ret void 387} 388 389define internal float @only_nofpclass_inf_callers(float %arg) { 390; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 391; CHECK-LABEL: define internal float @only_nofpclass_inf_callers 392; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { 393; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]] 394; CHECK-NEXT: ret float [[ADD]] 395; 396 %add = fadd float %arg, %arg 397 ret float %add 398} 399 400define float @call_noinf_0(float nofpclass(inf) %arg) { 401; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 402; TUNIT-LABEL: define float @call_noinf_0 403; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { 404; TUNIT-NEXT: [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]] 405; TUNIT-NEXT: ret float [[RESULT]] 406; 407; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 408; CGSCC-LABEL: define float @call_noinf_0 409; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { 410; CGSCC-NEXT: [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]] 411; CGSCC-NEXT: ret float [[RESULT]] 412; 413 %result = call float @only_nofpclass_inf_callers(float %arg) 414 ret float %result 415} 416 417define float @call_noinf_1(float %arg) { 418; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 419; TUNIT-LABEL: define float @call_noinf_1 420; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { 421; TUNIT-NEXT: [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]] 422; TUNIT-NEXT: ret float [[RESULT]] 423; 424; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 425; CGSCC-LABEL: define float @call_noinf_1 426; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] { 427; CGSCC-NEXT: [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]] 428; CGSCC-NEXT: ret float [[RESULT]] 429; 430 %result = call float @only_nofpclass_inf_callers(float nofpclass(inf) %arg) 431 ret float %result 432} 433 434; TODO: Should be able to infer nofpclass(inf) on return 435define internal float @only_nofpclass_inf_return_users(float %arg) { 436; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 437; CHECK-LABEL: define internal float @only_nofpclass_inf_return_users 438; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR3]] { 439; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]] 440; CHECK-NEXT: ret float [[ADD]] 441; 442 %add = fadd float %arg, %arg 443 ret float %add 444} 445 446define float @call_noinf_return_0(float %arg) { 447; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 448; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_0 449; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] { 450; TUNIT-NEXT: [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]] 451; TUNIT-NEXT: ret float [[RESULT]] 452; 453; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 454; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_0 455; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] { 456; CGSCC-NEXT: [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]] 457; CGSCC-NEXT: ret float [[RESULT]] 458; 459 %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg) 460 ret float %result 461} 462 463define float @call_noinf_return_1(float %arg) { 464; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 465; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_1 466; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] { 467; TUNIT-NEXT: [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]] 468; TUNIT-NEXT: ret float [[RESULT]] 469; 470; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 471; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_1 472; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] { 473; CGSCC-NEXT: [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]] 474; CGSCC-NEXT: ret float [[RESULT]] 475; 476 %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg) 477 ret float %result 478} 479 480define float @fcmp_olt_assume_one_0_callsite_arg_return(float %arg) { 481; CHECK-LABEL: define float @fcmp_olt_assume_one_0_callsite_arg_return 482; CHECK-SAME: (float returned [[ARG:%.*]]) { 483; CHECK-NEXT: entry: 484; CHECK-NEXT: [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp one float [[ARG]], 0.000000e+00 485; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]] 486; CHECK-NEXT: call void @extern.use(float [[ARG]]) 487; CHECK-NEXT: ret float [[ARG]] 488; 489entry: 490 %is.not.zero.or.nan = fcmp one float %arg, 0.0 491 call void @llvm.assume(i1 %is.not.zero.or.nan) 492 call void @extern.use(float %arg) 493 ret float %arg 494} 495 496define float @fcmp_olt_assume_une_0_callsite_arg_return(float %arg) { 497; CHECK-LABEL: define float @fcmp_olt_assume_une_0_callsite_arg_return 498; CHECK-SAME: (float returned [[ARG:%.*]]) { 499; CHECK-NEXT: entry: 500; CHECK-NEXT: [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00 501; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]] 502; CHECK-NEXT: call void @extern.use(float [[ARG]]) 503; CHECK-NEXT: ret float [[ARG]] 504; 505entry: 506 %is.not.zero.or.nan = fcmp une float %arg, 0.0 507 call void @llvm.assume(i1 %is.not.zero.or.nan) 508 call void @extern.use(float %arg) 509 ret float %arg 510} 511 512define half @fcmp_assume_issubnormal_callsite_arg_return(half %arg) { 513; CHECK-LABEL: define half @fcmp_assume_issubnormal_callsite_arg_return 514; CHECK-SAME: (half returned [[ARG:%.*]]) { 515; CHECK-NEXT: entry: 516; CHECK-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20:[0-9]+]] 517; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 518; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]] 519; CHECK-NEXT: call void @extern.use.f16(half [[ARG]]) 520; CHECK-NEXT: ret half [[ARG]] 521; 522entry: 523 %fabs = call half @llvm.fabs.f16(half %arg) 524 %is.subnormal = fcmp olt half %fabs, 0xH0400 525 call void @llvm.assume(i1 %is.subnormal) 526 call void @extern.use.f16(half %arg) 527 ret half %arg 528} 529 530; Assume is after the call, shouldn't mark callsite. 531define half @fcmp_assume_not_inf_after_call(half %arg) { 532; CHECK-LABEL: define half @fcmp_assume_not_inf_after_call 533; CHECK-SAME: (half returned [[ARG:%.*]]) { 534; CHECK-NEXT: entry: 535; CHECK-NEXT: call void @extern.use.f16(half [[ARG]]) 536; CHECK-NEXT: [[NOT_INF:%.*]] = fcmp oeq half [[ARG]], 0xH7C00 537; CHECK-NEXT: call void @llvm.assume(i1 noundef [[NOT_INF]]) 538; CHECK-NEXT: ret half [[ARG]] 539; 540entry: 541 call void @extern.use.f16(half %arg) 542 %not.inf = fcmp oeq half %arg, 0xH7C00 543 call void @llvm.assume(i1 %not.inf) 544 ret half %arg 545} 546 547; Assume not subnormal or zero, and not infinity 548define half @fcmp_assume2_callsite_arg_return(half %arg) { 549; CHECK-LABEL: define half @fcmp_assume2_callsite_arg_return 550; CHECK-SAME: (half returned [[ARG:%.*]]) { 551; CHECK-NEXT: entry: 552; CHECK-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]] 553; CHECK-NEXT: [[NOT_SUBNORMAL_OR_ZERO:%.*]] = fcmp oge half [[FABS]], 0xH0400 554; CHECK-NEXT: call void @llvm.assume(i1 noundef [[NOT_SUBNORMAL_OR_ZERO]]) #[[ATTR18]] 555; CHECK-NEXT: [[NOT_INF:%.*]] = fcmp one half [[ARG]], 0xH7C00 556; CHECK-NEXT: call void @llvm.assume(i1 noundef [[NOT_INF]]) #[[ATTR18]] 557; CHECK-NEXT: call void @extern.use.f16(half [[ARG]]) 558; CHECK-NEXT: ret half [[ARG]] 559; 560entry: 561 %fabs = call half @llvm.fabs.f16(half %arg) 562 %not.subnormal.or.zero = fcmp oge half %fabs, 0xH0400 563 call void @llvm.assume(i1 %not.subnormal.or.zero) 564 565 %not.inf = fcmp one half %arg, 0xH7C00 566 call void @llvm.assume(i1 %not.inf) 567 568 call void @extern.use.f16(half %arg) 569 ret half %arg 570} 571 572define float @is_fpclass_assume_arg_return(float %arg) { 573; CHECK-LABEL: define float @is_fpclass_assume_arg_return 574; CHECK-SAME: (float returned [[ARG:%.*]]) { 575; CHECK-NEXT: entry: 576; CHECK-NEXT: [[CLASS_TEST:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 292) #[[ATTR20]] 577; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CLASS_TEST]]) #[[ATTR18]] 578; CHECK-NEXT: call void @extern.use(float [[ARG]]) 579; CHECK-NEXT: ret float [[ARG]] 580; 581entry: 582 %class.test = call i1 @llvm.is.fpclass.f32(float %arg, i32 292) 583 call void @llvm.assume(i1 %class.test) 584 call void @extern.use(float %arg) 585 ret float %arg 586} 587 588; Make sure we don't get confused by looking at an unrelated assume 589; based on the fabs of the value. 590define half @assume_fcmp_fabs_with_other_fabs_assume(half %arg) { 591; CHECK-LABEL: define half @assume_fcmp_fabs_with_other_fabs_assume 592; CHECK-SAME: (half returned [[ARG:%.*]]) { 593; CHECK-NEXT: entry: 594; CHECK-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]] 595; CHECK-NEXT: [[UNRELATED_FABS:%.*]] = fcmp one half [[FABS]], 0xH0000 596; CHECK-NEXT: call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]] 597; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 598; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]] 599; CHECK-NEXT: call void @extern.use.f16(half [[ARG]]) 600; CHECK-NEXT: call void @extern.use.f16(half nofpclass(ninf nzero nsub nnorm) [[FABS]]) 601; CHECK-NEXT: ret half [[ARG]] 602; 603entry: 604 605 %fabs = call half @llvm.fabs.f16(half %arg) 606 %unrelated.fabs = fcmp one half %fabs, 0.0 607 call void @llvm.assume(i1 %unrelated.fabs) 608 %is.subnormal = fcmp olt half %fabs, 0xH0400 609 call void @llvm.assume(i1 %is.subnormal) 610 call void @extern.use.f16(half %arg) 611 call void @extern.use.f16(half %fabs) 612 ret half %arg 613} 614 615; Make sure if looking through the fabs finds a different source 616; value, we still identify a test mask by ignoring the fabs 617define half @assume_fcmp_fabs_with_other_fabs_assume_fallback(half %arg) { 618; CHECK-LABEL: define half @assume_fcmp_fabs_with_other_fabs_assume_fallback 619; CHECK-SAME: (half returned [[ARG:%.*]]) { 620; CHECK-NEXT: entry: 621; CHECK-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]] 622; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR18]] 623; CHECK-NEXT: [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000 624; CHECK-NEXT: call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]] 625; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR18]] 626; CHECK-NEXT: call void @extern.use.f16(half [[ARG]]) 627; CHECK-NEXT: call void @extern.use.f16(half nofpclass(ninf nzero nsub nnorm) [[FABS]]) 628; CHECK-NEXT: ret half [[ARG]] 629; 630entry: 631 632 %fabs = call half @llvm.fabs.f16(half %arg) 633 634 %one.inf = fcmp one half %arg, 0xH7C00 635 call void @llvm.assume(i1 %one.inf) 636 637 %unrelated.fabs = fcmp oeq half %fabs, 0.0 638 call void @llvm.assume(i1 %unrelated.fabs) 639 640 %is.subnormal = fcmp olt half %fabs, 0xH0400 641 call void @llvm.assume(i1 %is.subnormal) 642 call void @extern.use.f16(half %arg) 643 call void @extern.use.f16(half %fabs) 644 ret half %arg 645} 646 647define float @assume_bundles(i1 %c, float %ret) { 648; CHECK-LABEL: define float @assume_bundles 649; CHECK-SAME: (i1 noundef [[C:%.*]], float returned [[RET:%.*]]) { 650; CHECK-NEXT: entry: 651; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 652; CHECK: A: 653; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR18]] [ "nofpclass"(float [[RET]], i32 3) ] 654; CHECK-NEXT: call void @extern.use(float nofpclass(nan) [[RET]]) 655; CHECK-NEXT: ret float [[RET]] 656; CHECK: B: 657; CHECK-NEXT: call void @llvm.assume(i1 noundef true) [ "nofpclass"(float [[RET]], i32 12) ] 658; CHECK-NEXT: call void @extern.use(float nofpclass(ninf nnorm) [[RET]]) 659; CHECK-NEXT: ret float [[RET]] 660; 661entry: 662 br i1 %c, label %A, label %B 663 664A: 665 call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 3) ] 666 call void @extern.use(float %ret) 667 ret float %ret 668 669B: 670 call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 12) ] 671 call void @extern.use(float %ret) 672 ret float %ret 673} 674 675define float @returned_load(ptr %ptr) { 676; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) 677; CHECK-LABEL: define float @returned_load 678; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[PTR:%.*]]) #[[ATTR5:[0-9]+]] { 679; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR]], align 4 680; CHECK-NEXT: ret float [[LOAD]] 681; 682 %load = load float, ptr %ptr 683 ret float %load 684} 685 686define float @pass_nofpclass_inf_through_memory(float nofpclass(inf) %arg) { 687; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 688; TUNIT-LABEL: define float @pass_nofpclass_inf_through_memory 689; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { 690; TUNIT-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 691; TUNIT-NEXT: store float [[ARG]], ptr [[ALLOCA]], align 4 692; TUNIT-NEXT: [[RET:%.*]] = call float @returned_load(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]] 693; TUNIT-NEXT: ret float [[RET]] 694; 695; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 696; CGSCC-LABEL: define float @pass_nofpclass_inf_through_memory 697; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] { 698; CGSCC-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 699; CGSCC-NEXT: store float [[ARG]], ptr [[ALLOCA]], align 4 700; CGSCC-NEXT: [[RET:%.*]] = call float @returned_load(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]] 701; CGSCC-NEXT: ret float [[RET]] 702; 703 %alloca = alloca float 704 store float %arg, ptr %alloca 705 %ret = call float @returned_load(ptr %alloca) 706 ret float %ret 707} 708 709define float @returned_fabs(float %x) { 710; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 711; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs 712; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] { 713; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22:[0-9]+]] 714; TUNIT-NEXT: ret float [[FABS]] 715; 716; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 717; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs 718; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] { 719; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]] 720; CGSCC-NEXT: ret float [[FABS]] 721; 722 %fabs = call float @llvm.fabs.f32(float %x) 723 ret float %fabs 724} 725 726define float @returned_fabs_nosnan(float nofpclass(snan) %x) { 727; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 728; TUNIT-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan 729; TUNIT-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 730; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR22]] 731; TUNIT-NEXT: ret float [[FABS]] 732; 733; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 734; CGSCC-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan 735; CGSCC-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 736; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR19]] 737; CGSCC-NEXT: ret float [[FABS]] 738; 739 %fabs = call float @llvm.fabs.f32(float %x) 740 ret float %fabs 741} 742 743define float @returned_fabs_noqnan(float nofpclass(qnan) %x) { 744; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 745; TUNIT-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan 746; TUNIT-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] { 747; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR22]] 748; TUNIT-NEXT: ret float [[FABS]] 749; 750; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 751; CGSCC-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan 752; CGSCC-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] { 753; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR19]] 754; CGSCC-NEXT: ret float [[FABS]] 755; 756 %fabs = call float @llvm.fabs.f32(float %x) 757 ret float %fabs 758} 759 760define float @returned_fabs_nonan(float nofpclass(nan) %x) { 761; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 762; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan 763; TUNIT-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { 764; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR22]] 765; TUNIT-NEXT: ret float [[FABS]] 766; 767; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 768; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan 769; CGSCC-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { 770; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR19]] 771; CGSCC-NEXT: ret float [[FABS]] 772; 773 %fabs = call float @llvm.fabs.f32(float %x) 774 ret float %fabs 775} 776 777define float @returned_fabs_noinf(float nofpclass(inf) %x) { 778; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 779; TUNIT-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf 780; TUNIT-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] { 781; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf) [[X]]) #[[ATTR22]] 782; TUNIT-NEXT: ret float [[FABS]] 783; 784; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 785; CGSCC-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf 786; CGSCC-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] { 787; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf) [[X]]) #[[ATTR19]] 788; CGSCC-NEXT: ret float [[FABS]] 789; 790 %fabs = call float @llvm.fabs.f32(float %x) 791 ret float %fabs 792} 793 794define float @returned_fabs_nopos(float nofpclass(psub pnorm pinf) %x) { 795; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 796; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos 797; TUNIT-SAME: (float nofpclass(pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] { 798; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf psub pnorm) [[X]]) #[[ATTR22]] 799; TUNIT-NEXT: ret float [[FABS]] 800; 801; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 802; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos 803; CGSCC-SAME: (float nofpclass(pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] { 804; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf psub pnorm) [[X]]) #[[ATTR19]] 805; CGSCC-NEXT: ret float [[FABS]] 806; 807 %fabs = call float @llvm.fabs.f32(float %x) 808 ret float %fabs 809} 810 811define float @returned_fabs_nopos_nopzero(float nofpclass(psub pnorm pinf pzero) %x) { 812; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 813; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero 814; TUNIT-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 815; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR22]] 816; TUNIT-NEXT: ret float [[FABS]] 817; 818; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 819; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero 820; CGSCC-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 821; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR19]] 822; CGSCC-NEXT: ret float [[FABS]] 823; 824 %fabs = call float @llvm.fabs.f32(float %x) 825 ret float %fabs 826} 827 828define float @returned_fabs_nopos_nozero(float nofpclass(psub pnorm pinf zero) %x) { 829; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 830; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero 831; TUNIT-SAME: (float nofpclass(pinf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 832; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf zero psub pnorm) [[X]]) #[[ATTR22]] 833; TUNIT-NEXT: ret float [[FABS]] 834; 835; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 836; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero 837; CGSCC-SAME: (float nofpclass(pinf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 838; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf zero psub pnorm) [[X]]) #[[ATTR19]] 839; CGSCC-NEXT: ret float [[FABS]] 840; 841 %fabs = call float @llvm.fabs.f32(float %x) 842 ret float %fabs 843} 844 845define float @returned_fabs_nopos_nonan(float nofpclass(psub pnorm pinf nan) %x) { 846; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 847; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan 848; TUNIT-SAME: (float nofpclass(nan pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] { 849; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan pinf psub pnorm) [[X]]) #[[ATTR22]] 850; TUNIT-NEXT: ret float [[FABS]] 851; 852; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 853; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan 854; CGSCC-SAME: (float nofpclass(nan pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] { 855; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan pinf psub pnorm) [[X]]) #[[ATTR19]] 856; CGSCC-NEXT: ret float [[FABS]] 857; 858 %fabs = call float @llvm.fabs.f32(float %x) 859 ret float %fabs 860} 861 862define float @returned_fabs_noneg(float nofpclass(nsub nnorm ninf) %x) { 863; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 864; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg 865; TUNIT-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 866; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nsub nnorm) [[X]]) #[[ATTR22]] 867; TUNIT-NEXT: ret float [[FABS]] 868; 869; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 870; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg 871; CGSCC-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 872; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nsub nnorm) [[X]]) #[[ATTR19]] 873; CGSCC-NEXT: ret float [[FABS]] 874; 875 %fabs = call float @llvm.fabs.f32(float %x) 876 ret float %fabs 877} 878 879define float @returned_fabs_noneg_nonzero(float nofpclass(nsub nnorm ninf nzero) %x) { 880; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 881; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero 882; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 883; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]] 884; TUNIT-NEXT: ret float [[FABS]] 885; 886; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 887; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero 888; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 889; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]] 890; CGSCC-NEXT: ret float [[FABS]] 891; 892 %fabs = call float @llvm.fabs.f32(float %x) 893 ret float %fabs 894} 895 896define float @returned_fabs_noneg_nozero(float nofpclass(nsub nnorm ninf zero) %x) { 897; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 898; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero 899; TUNIT-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 900; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR22]] 901; TUNIT-NEXT: ret float [[FABS]] 902; 903; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 904; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero 905; CGSCC-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 906; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR19]] 907; CGSCC-NEXT: ret float [[FABS]] 908; 909 %fabs = call float @llvm.fabs.f32(float %x) 910 ret float %fabs 911} 912 913define float @returned_fabs_noneg_nonan(float nofpclass(nsub nnorm ninf nan) %x) { 914; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 915; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan 916; TUNIT-SAME: (float nofpclass(nan ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 917; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nsub nnorm) [[X]]) #[[ATTR22]] 918; TUNIT-NEXT: ret float [[FABS]] 919; 920; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 921; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan 922; CGSCC-SAME: (float nofpclass(nan ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 923; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nsub nnorm) [[X]]) #[[ATTR19]] 924; CGSCC-NEXT: ret float [[FABS]] 925; 926 %fabs = call float @llvm.fabs.f32(float %x) 927 ret float %fabs 928} 929 930define float @returned_fabs_nonsub_nopnorm_nonzero(float nofpclass(nsub pnorm nzero) %x) { 931; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 932; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero 933; TUNIT-SAME: (float nofpclass(nzero nsub pnorm) [[X:%.*]]) #[[ATTR3]] { 934; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nsub pnorm) [[X]]) #[[ATTR22]] 935; TUNIT-NEXT: ret float [[FABS]] 936; 937; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 938; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero 939; CGSCC-SAME: (float nofpclass(nzero nsub pnorm) [[X:%.*]]) #[[ATTR3]] { 940; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nsub pnorm) [[X]]) #[[ATTR19]] 941; CGSCC-NEXT: ret float [[FABS]] 942; 943 %fabs = call float @llvm.fabs.f32(float %x) 944 ret float %fabs 945} 946 947define float @returned_fabs_nopsub_nonnorm_nopzero(float nofpclass(psub nnorm pzero) %x) { 948; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 949; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero 950; TUNIT-SAME: (float nofpclass(pzero psub nnorm) [[X:%.*]]) #[[ATTR3]] { 951; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pzero psub nnorm) [[X]]) #[[ATTR22]] 952; TUNIT-NEXT: ret float [[FABS]] 953; 954; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 955; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero 956; CGSCC-SAME: (float nofpclass(pzero psub nnorm) [[X:%.*]]) #[[ATTR3]] { 957; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pzero psub nnorm) [[X]]) #[[ATTR19]] 958; CGSCC-NEXT: ret float [[FABS]] 959; 960 %fabs = call float @llvm.fabs.f32(float %x) 961 ret float %fabs 962} 963 964define float @returned_fabs_nonnorm_nozero(float nofpclass(nnorm nzero) %x) { 965; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 966; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero 967; TUNIT-SAME: (float nofpclass(nzero nnorm) [[X:%.*]]) #[[ATTR3]] { 968; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nnorm) [[X]]) #[[ATTR22]] 969; TUNIT-NEXT: ret float [[FABS]] 970; 971; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 972; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero 973; CGSCC-SAME: (float nofpclass(nzero nnorm) [[X:%.*]]) #[[ATTR3]] { 974; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nnorm) [[X]]) #[[ATTR19]] 975; CGSCC-NEXT: ret float [[FABS]] 976; 977 %fabs = call float @llvm.fabs.f32(float %x) 978 ret float %fabs 979} 980 981define float @returned_fneg(float %x) { 982; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 983; CHECK-LABEL: define float @returned_fneg 984; CHECK-SAME: (float [[X:%.*]]) #[[ATTR3]] { 985; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 986; CHECK-NEXT: ret float [[FNEG]] 987; 988 %fneg = fneg float %x 989 ret float %fneg 990} 991 992define float @returned_fneg_nosnan(float nofpclass(snan) %x) { 993; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 994; CHECK-LABEL: define nofpclass(snan) float @returned_fneg_nosnan 995; CHECK-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 996; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 997; CHECK-NEXT: ret float [[FNEG]] 998; 999 %fneg = fneg float %x 1000 ret float %fneg 1001} 1002 1003define float @returned_fneg_noqnan(float nofpclass(qnan) %x) { 1004; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1005; CHECK-LABEL: define nofpclass(qnan) float @returned_fneg_noqnan 1006; CHECK-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] { 1007; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1008; CHECK-NEXT: ret float [[FNEG]] 1009; 1010 %fneg = fneg float %x 1011 ret float %fneg 1012} 1013 1014define float @returned_fneg_nosnan_ninf_flag(float nofpclass(snan) %x) { 1015; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1016; CHECK-LABEL: define nofpclass(snan inf) float @returned_fneg_nosnan_ninf_flag 1017; CHECK-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 1018; CHECK-NEXT: [[FNEG:%.*]] = fneg ninf float [[X]] 1019; CHECK-NEXT: ret float [[FNEG]] 1020; 1021 %fneg = fneg ninf float %x 1022 ret float %fneg 1023} 1024 1025define float @returned_fneg_nonan(float nofpclass(nan) %x) { 1026; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1027; CHECK-LABEL: define nofpclass(nan) float @returned_fneg_nonan 1028; CHECK-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { 1029; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1030; CHECK-NEXT: ret float [[FNEG]] 1031; 1032 %fneg = fneg float %x 1033 ret float %fneg 1034} 1035 1036define float @returned_fneg_noinf(float nofpclass(inf) %x) { 1037; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1038; CHECK-LABEL: define nofpclass(inf) float @returned_fneg_noinf 1039; CHECK-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] { 1040; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1041; CHECK-NEXT: ret float [[FNEG]] 1042; 1043 %fneg = fneg float %x 1044 ret float %fneg 1045} 1046 1047define float @returned_fneg_noneg(float nofpclass(ninf nsub nnorm nzero) %x) { 1048; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1049; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_noneg 1050; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 1051; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1052; CHECK-NEXT: ret float [[FNEG]] 1053; 1054 %fneg = fneg float %x 1055 ret float %fneg 1056} 1057 1058define float @returned_fneg_noneg_nnan_flag(float nofpclass(ninf nsub nnorm nzero) %x) { 1059; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1060; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_noneg_nnan_flag 1061; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 1062; CHECK-NEXT: [[FNEG:%.*]] = fneg nnan float [[X]] 1063; CHECK-NEXT: ret float [[FNEG]] 1064; 1065 %fneg = fneg nnan float %x 1066 ret float %fneg 1067} 1068 1069define float @returned_fneg_nonsubnnorm(float nofpclass(nsub nnorm) %x) { 1070; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1071; CHECK-LABEL: define nofpclass(psub pnorm) float @returned_fneg_nonsubnnorm 1072; CHECK-SAME: (float nofpclass(nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 1073; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1074; CHECK-NEXT: ret float [[FNEG]] 1075; 1076 %fneg = fneg float %x 1077 ret float %fneg 1078} 1079 1080define float @returned_fneg_nopos(float nofpclass(pinf psub pnorm pzero) %x) { 1081; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1082; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fneg_nopos 1083; CHECK-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 1084; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1085; CHECK-NEXT: ret float [[FNEG]] 1086; 1087 %fneg = fneg float %x 1088 ret float %fneg 1089} 1090 1091define float @returned_fneg_nopnormpsub(float nofpclass(psub pnorm) %x) { 1092; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1093; CHECK-LABEL: define nofpclass(nsub nnorm) float @returned_fneg_nopnormpsub 1094; CHECK-SAME: (float nofpclass(psub pnorm) [[X:%.*]]) #[[ATTR3]] { 1095; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1096; CHECK-NEXT: ret float [[FNEG]] 1097; 1098 %fneg = fneg float %x 1099 ret float %fneg 1100} 1101 1102define float @returned_fneg_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) { 1103; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1104; CHECK-LABEL: define nofpclass(qnan pinf pzero nsub pnorm) float @returned_fneg_mixed 1105; CHECK-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] { 1106; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]] 1107; CHECK-NEXT: ret float [[FNEG]] 1108; 1109 %fneg = fneg float %x 1110 ret float %fneg 1111} 1112 1113define float @returned_fneg_fabs(float %x) { 1114; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1115; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs 1116; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1117; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]] 1118; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1119; TUNIT-NEXT: ret float [[FNEG_FABS]] 1120; 1121; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1122; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs 1123; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1124; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]] 1125; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1126; CGSCC-NEXT: ret float [[FNEG_FABS]] 1127; 1128 %fabs = call float @llvm.fabs.f32(float %x) 1129 %fneg.fabs = fneg float %fabs 1130 ret float %fneg.fabs 1131} 1132 1133define float @returned_fneg_fabs_nosnan(float nofpclass(snan) %x) { 1134; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1135; TUNIT-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan 1136; TUNIT-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 1137; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR22]] 1138; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1139; TUNIT-NEXT: ret float [[FNEG_FABS]] 1140; 1141; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1142; CGSCC-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan 1143; CGSCC-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] { 1144; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR19]] 1145; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1146; CGSCC-NEXT: ret float [[FNEG_FABS]] 1147; 1148 %fabs = call float @llvm.fabs.f32(float %x) 1149 %fneg.fabs = fneg float %fabs 1150 ret float %fneg.fabs 1151} 1152 1153define float @returned_fneg_fabs_noqnan(float nofpclass(qnan) %x) { 1154; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1155; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan 1156; TUNIT-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] { 1157; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR22]] 1158; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1159; TUNIT-NEXT: ret float [[FNEG_FABS]] 1160; 1161; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1162; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan 1163; CGSCC-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] { 1164; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR19]] 1165; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1166; CGSCC-NEXT: ret float [[FNEG_FABS]] 1167; 1168 %fabs = call float @llvm.fabs.f32(float %x) 1169 %fneg.fabs = fneg float %fabs 1170 ret float %fneg.fabs 1171} 1172 1173define float @returned_fneg_fabs_nonan(float nofpclass(nan) %x) { 1174; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1175; TUNIT-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan 1176; TUNIT-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { 1177; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR22]] 1178; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1179; TUNIT-NEXT: ret float [[FNEG_FABS]] 1180; 1181; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1182; CGSCC-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan 1183; CGSCC-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] { 1184; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR19]] 1185; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1186; CGSCC-NEXT: ret float [[FNEG_FABS]] 1187; 1188 %fabs = call float @llvm.fabs.f32(float %x) 1189 %fneg.fabs = fneg float %fabs 1190 ret float %fneg.fabs 1191} 1192 1193define float @returned_fneg_fabs_noneg(float nofpclass(ninf nsub nnorm nzero) %x) { 1194; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1195; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg 1196; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 1197; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]] 1198; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1199; TUNIT-NEXT: ret float [[FNEG_FABS]] 1200; 1201; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1202; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg 1203; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] { 1204; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]] 1205; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1206; CGSCC-NEXT: ret float [[FNEG_FABS]] 1207; 1208 %fabs = call float @llvm.fabs.f32(float %x) 1209 %fneg.fabs = fneg float %fabs 1210 ret float %fneg.fabs 1211} 1212 1213define float @returned_fneg_fabs_nopos(float nofpclass(pinf psub pnorm pzero) %x) { 1214; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1215; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos 1216; TUNIT-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 1217; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR22]] 1218; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1219; TUNIT-NEXT: ret float [[FNEG_FABS]] 1220; 1221; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1222; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos 1223; CGSCC-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] { 1224; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR19]] 1225; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1226; CGSCC-NEXT: ret float [[FNEG_FABS]] 1227; 1228 %fabs = call float @llvm.fabs.f32(float %x) 1229 %fneg.fabs = fneg float %fabs 1230 ret float %fneg.fabs 1231} 1232 1233define float @returned_fneg_fabs_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) { 1234; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1235; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed 1236; TUNIT-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] { 1237; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero psub nnorm) [[X]]) #[[ATTR22]] 1238; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1239; TUNIT-NEXT: ret float [[FNEG_FABS]] 1240; 1241; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1242; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed 1243; CGSCC-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] { 1244; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero psub nnorm) [[X]]) #[[ATTR19]] 1245; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1246; CGSCC-NEXT: ret float [[FNEG_FABS]] 1247; 1248 %fabs = call float @llvm.fabs.f32(float %x) 1249 %fneg.fabs = fneg float %fabs 1250 ret float %fneg.fabs 1251} 1252 1253define float @returned_fneg_fabs_ninf_flag_fabs(float %x) { 1254; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1255; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs 1256; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1257; TUNIT-NEXT: [[FABS:%.*]] = call ninf nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]] 1258; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1259; TUNIT-NEXT: ret float [[FNEG_FABS]] 1260; 1261; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1262; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs 1263; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1264; CGSCC-NEXT: [[FABS:%.*]] = call ninf nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]] 1265; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg float [[FABS]] 1266; CGSCC-NEXT: ret float [[FNEG_FABS]] 1267; 1268 %fabs = call ninf float @llvm.fabs.f32(float %x) 1269 %fneg.fabs = fneg float %fabs 1270 ret float %fneg.fabs 1271} 1272 1273define float @returned_fneg_fabs_ninf_flag_fneg(float %x) { 1274; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1275; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg 1276; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1277; TUNIT-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]] 1278; TUNIT-NEXT: [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]] 1279; TUNIT-NEXT: ret float [[FNEG_FABS]] 1280; 1281; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1282; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg 1283; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] { 1284; CGSCC-NEXT: [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]] 1285; CGSCC-NEXT: [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]] 1286; CGSCC-NEXT: ret float [[FNEG_FABS]] 1287; 1288 %fabs = call float @llvm.fabs.f32(float %x) 1289 %fneg.fabs = fneg ninf float %fabs 1290 ret float %fneg.fabs 1291} 1292 1293define float @uitofp_i32_to_f32(i32 %arg) { 1294; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1295; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) float @uitofp_i32_to_f32 1296; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 1297; CHECK-NEXT: [[CVT:%.*]] = uitofp i32 [[ARG]] to float 1298; CHECK-NEXT: ret float [[CVT]] 1299; 1300 %cvt = uitofp i32 %arg to float 1301 ret float %cvt 1302} 1303 1304define float @sitofp_i32_to_f32(i32 %arg) { 1305; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1306; CHECK-LABEL: define nofpclass(nan inf nzero sub) float @sitofp_i32_to_f32 1307; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 1308; CHECK-NEXT: [[CVT:%.*]] = sitofp i32 [[ARG]] to float 1309; CHECK-NEXT: ret float [[CVT]] 1310; 1311 %cvt = sitofp i32 %arg to float 1312 ret float %cvt 1313} 1314 1315define <2 x float> @uitofp_v2i32_to_v2f32(<2 x i32> %arg) { 1316; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1317; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) <2 x float> @uitofp_v2i32_to_v2f32 1318; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 1319; CHECK-NEXT: [[CVT:%.*]] = uitofp <2 x i32> [[ARG]] to <2 x float> 1320; CHECK-NEXT: ret <2 x float> [[CVT]] 1321; 1322 %cvt = uitofp <2 x i32> %arg to <2 x float> 1323 ret <2 x float> %cvt 1324} 1325 1326define <2 x float> @sitofp_v2i32_to_v2i32(<2 x i32> %arg) { 1327; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1328; CHECK-LABEL: define nofpclass(nan inf nzero sub) <2 x float> @sitofp_v2i32_to_v2i32 1329; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 1330; CHECK-NEXT: [[CVT:%.*]] = sitofp <2 x i32> [[ARG]] to <2 x float> 1331; CHECK-NEXT: ret <2 x float> [[CVT]] 1332; 1333 %cvt = sitofp <2 x i32> %arg to <2 x float> 1334 ret <2 x float> %cvt 1335} 1336 1337define half @uitofp_i17_to_f16(i17 %arg) { 1338; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1339; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) half @uitofp_i17_to_f16 1340; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] { 1341; CHECK-NEXT: [[CVT:%.*]] = uitofp i17 [[ARG]] to half 1342; CHECK-NEXT: ret half [[CVT]] 1343; 1344 %cvt = uitofp i17 %arg to half 1345 ret half %cvt 1346} 1347 1348define half @sitofp_i17_to_f16(i17 %arg) { 1349; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1350; CHECK-LABEL: define nofpclass(nan nzero sub) half @sitofp_i17_to_f16 1351; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] { 1352; CHECK-NEXT: [[CVT:%.*]] = sitofp i17 [[ARG]] to half 1353; CHECK-NEXT: ret half [[CVT]] 1354; 1355 %cvt = sitofp i17 %arg to half 1356 ret half %cvt 1357} 1358 1359define <2 x half> @uitofp_v2i17_to_v2f16(<2 x i17> %arg) { 1360; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1361; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) <2 x half> @uitofp_v2i17_to_v2f16 1362; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] { 1363; CHECK-NEXT: [[CVT:%.*]] = uitofp <2 x i17> [[ARG]] to <2 x half> 1364; CHECK-NEXT: ret <2 x half> [[CVT]] 1365; 1366 %cvt = uitofp <2 x i17> %arg to <2 x half> 1367 ret <2 x half> %cvt 1368} 1369 1370define <2 x half> @sitofp_v2i17_to_v2i17(<2 x i17> %arg) { 1371; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1372; CHECK-LABEL: define nofpclass(nan nzero sub) <2 x half> @sitofp_v2i17_to_v2i17 1373; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] { 1374; CHECK-NEXT: [[CVT:%.*]] = sitofp <2 x i17> [[ARG]] to <2 x half> 1375; CHECK-NEXT: ret <2 x half> [[CVT]] 1376; 1377 %cvt = sitofp <2 x i17> %arg to <2 x half> 1378 ret <2 x half> %cvt 1379} 1380 1381define float @assume_intersection_not_zero_and_not_nan(float %arg) { 1382; CHECK-LABEL: define float @assume_intersection_not_zero_and_not_nan 1383; CHECK-SAME: (float returned [[ARG:%.*]]) { 1384; CHECK-NEXT: entry: 1385; CHECK-NEXT: [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00 1386; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]] 1387; CHECK-NEXT: [[IS_ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00 1388; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_ORD]]) #[[ATTR18]] 1389; CHECK-NEXT: call void @extern.use(float [[ARG]]) 1390; CHECK-NEXT: ret float [[ARG]] 1391; 1392entry: 1393 %is.not.zero.or.nan = fcmp une float %arg, 0.0 1394 call void @llvm.assume(i1 %is.not.zero.or.nan) 1395 %is.ord = fcmp ord float %arg, 0.0 1396 call void @llvm.assume(i1 %is.ord) 1397 call void @extern.use(float %arg) 1398 ret float %arg 1399} 1400 1401define float @assume_intersection_class(float %arg) { 1402; CHECK-LABEL: define float @assume_intersection_class 1403; CHECK-SAME: (float returned [[ARG:%.*]]) { 1404; CHECK-NEXT: entry: 1405; CHECK-NEXT: [[POS_NORMAL_OR_POS_SUBNORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 384) #[[ATTR20]] 1406; CHECK-NEXT: call void @llvm.assume(i1 noundef [[POS_NORMAL_OR_POS_SUBNORMAL]]) #[[ATTR18]] 1407; CHECK-NEXT: [[IS_NORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 264) #[[ATTR20]] 1408; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_NORMAL]]) #[[ATTR18]] 1409; CHECK-NEXT: call void @extern.use(float [[ARG]]) 1410; CHECK-NEXT: ret float [[ARG]] 1411; 1412entry: 1413 %pos.normal.or.pos.subnormal = call i1 @llvm.is.fpclass.f32(float %arg, i32 384) 1414 call void @llvm.assume(i1 %pos.normal.or.pos.subnormal) 1415 %is.normal = call i1 @llvm.is.fpclass.f32(float %arg, i32 264) 1416 call void @llvm.assume(i1 %is.normal) 1417 1418 call void @extern.use(float %arg) 1419 ret float %arg 1420} 1421 1422define float @assume_intersection_none(float %arg) { 1423; CHECK-LABEL: define float @assume_intersection_none 1424; CHECK-SAME: (float returned [[ARG:%.*]]) { 1425; CHECK-NEXT: entry: 1426; CHECK-NEXT: [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 682) #[[ATTR20]] 1427; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CLASS1]]) #[[ATTR18]] 1428; CHECK-NEXT: [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 341) #[[ATTR20]] 1429; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CLASS2]]) #[[ATTR18]] 1430; CHECK-NEXT: call void @extern.use(float [[ARG]]) 1431; CHECK-NEXT: ret float [[ARG]] 1432; 1433entry: 1434 %class1 = call i1 @llvm.is.fpclass.f32(float %arg, i32 682) 1435 call void @llvm.assume(i1 %class1) 1436 %class2 = call i1 @llvm.is.fpclass.f32(float %arg, i32 341) 1437 call void @llvm.assume(i1 %class2) 1438 call void @extern.use(float %arg) 1439 ret float %arg 1440} 1441 1442define float @returned_extractelement_dynamic_index(<4 x float> nofpclass(nan) %vec, i32 %idx) { 1443; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1444; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_dynamic_index 1445; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] { 1446; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 [[IDX]] 1447; CHECK-NEXT: ret float [[EXTRACT]] 1448; 1449 %extract = extractelement <4 x float> %vec, i32 %idx 1450 ret float %extract 1451} 1452 1453define float @returned_extractelement_index0(<4 x float> nofpclass(nan) %vec) { 1454; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1455; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index0 1456; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] { 1457; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 0 1458; CHECK-NEXT: ret float [[EXTRACT]] 1459; 1460 %extract = extractelement <4 x float> %vec, i32 0 1461 ret float %extract 1462} 1463 1464define float @returned_extractelement_index_oob(<4 x float> nofpclass(nan) %vec) { 1465; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1466; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index_oob 1467; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] { 1468; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 5 1469; CHECK-NEXT: ret float [[EXTRACT]] 1470; 1471 %extract = extractelement <4 x float> %vec, i32 5 1472 ret float %extract 1473} 1474 1475define float @returned_extractelement_scalable(<vscale x 4 x float> nofpclass(nan) %vec) { 1476; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1477; CHECK-LABEL: define float @returned_extractelement_scalable 1478; CHECK-SAME: (<vscale x 4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] { 1479; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <vscale x 4 x float> [[VEC]], i32 0 1480; CHECK-NEXT: ret float [[EXTRACT]] 1481; 1482 %extract = extractelement <vscale x 4 x float> %vec, i32 0 1483 ret float %extract 1484} 1485 1486define float @returned_extractvalue([4 x float] nofpclass(nan) %array) { 1487; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1488; CHECK-LABEL: define nofpclass(nan) float @returned_extractvalue 1489; CHECK-SAME: ([4 x float] nofpclass(nan) [[ARRAY:%.*]]) #[[ATTR3]] { 1490; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue [4 x float] [[ARRAY]], 0 1491; CHECK-NEXT: ret float [[EXTRACT]] 1492; 1493 %extract = extractvalue [4 x float] %array, 0 1494 ret float %extract 1495} 1496 1497define float @return_nofpclass_freeze_nan_arg(float nofpclass(nan) %arg) { 1498; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1499; CHECK-LABEL: define noundef float @return_nofpclass_freeze_nan_arg 1500; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR3]] { 1501; CHECK-NEXT: [[FREEZE:%.*]] = freeze float [[ARG]] 1502; CHECK-NEXT: ret float [[FREEZE]] 1503; 1504 %freeze = freeze float %arg 1505 ret float %freeze 1506} 1507 1508define float @return_nofpclass_extractelement_freeze_pinf_arg(<2 x float> nofpclass(pinf) %arg) { 1509; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1510; CHECK-LABEL: define noundef float @return_nofpclass_extractelement_freeze_pinf_arg 1511; CHECK-SAME: (<2 x float> nofpclass(pinf) [[ARG:%.*]]) #[[ATTR3]] { 1512; CHECK-NEXT: [[FREEZE:%.*]] = freeze <2 x float> [[ARG]] 1513; CHECK-NEXT: [[ELT:%.*]] = extractelement <2 x float> [[FREEZE]], i32 0 1514; CHECK-NEXT: ret float [[ELT]] 1515; 1516 %freeze = freeze <2 x float> %arg 1517 %elt = extractelement <2 x float> %freeze, i32 0 1518 ret float %elt 1519} 1520 1521define <4 x float> @insertelement_constant_chain() { 1522; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1523; CHECK-LABEL: define nofpclass(nan ninf nzero sub) <4 x float> @insertelement_constant_chain 1524; CHECK-SAME: () #[[ATTR3]] { 1525; CHECK-NEXT: [[INS_0:%.*]] = insertelement <4 x float> poison, float 1.000000e+00, i32 0 1526; CHECK-NEXT: [[INS_1:%.*]] = insertelement <4 x float> [[INS_0]], float 0.000000e+00, i32 1 1527; CHECK-NEXT: [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float -9.000000e+00, i32 2 1528; CHECK-NEXT: [[INS_3:%.*]] = insertelement <4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3 1529; CHECK-NEXT: ret <4 x float> [[INS_3]] 1530; 1531 %ins.0 = insertelement <4 x float> poison, float 1.0, i32 0 1532 %ins.1 = insertelement <4 x float> %ins.0, float 0.0, i32 1 1533 %ins.2 = insertelement <4 x float> %ins.1, float -9.0, i32 2 1534 %ins.3 = insertelement <4 x float> %ins.2, float 0x7FF0000000000000, i32 3 1535 ret <4 x float> %ins.3 1536} 1537 1538define <4 x float> @insertelement_non_constant_chain(i32 %idx) { 1539; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1540; CHECK-LABEL: define nofpclass(nan inf nzero sub) <4 x float> @insertelement_non_constant_chain 1541; CHECK-SAME: (i32 [[IDX:%.*]]) #[[ATTR3]] { 1542; CHECK-NEXT: [[INS_0:%.*]] = insertelement <4 x float> poison, float 1.000000e+00, i32 0 1543; CHECK-NEXT: [[INS_1:%.*]] = insertelement <4 x float> [[INS_0]], float 0.000000e+00, i32 1 1544; CHECK-NEXT: [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float -9.000000e+00, i32 2 1545; CHECK-NEXT: [[INS_3:%.*]] = insertelement <4 x float> [[INS_2]], float 3.000000e+00, i32 3 1546; CHECK-NEXT: [[INS_4:%.*]] = insertelement <4 x float> [[INS_2]], float 4.000000e+00, i32 [[IDX]] 1547; CHECK-NEXT: ret <4 x float> [[INS_4]] 1548; 1549 %ins.0 = insertelement <4 x float> poison, float 1.0, i32 0 1550 %ins.1 = insertelement <4 x float> %ins.0, float 0.0, i32 1 1551 %ins.2 = insertelement <4 x float> %ins.1, float -9.0, i32 2 1552 %ins.3 = insertelement <4 x float> %ins.2, float 3.0, i32 3 1553 %ins.4 = insertelement <4 x float> %ins.2, float 4.0, i32 %idx 1554 ret <4 x float> %ins.4 1555} 1556 1557define <vscale x 4 x float> @insertelement_scalable_constant_chain() { 1558; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1559; CHECK-LABEL: define <vscale x 4 x float> @insertelement_scalable_constant_chain 1560; CHECK-SAME: () #[[ATTR3]] { 1561; CHECK-NEXT: [[INS_0:%.*]] = insertelement <vscale x 4 x float> poison, float 1.000000e+00, i32 0 1562; CHECK-NEXT: [[INS_1:%.*]] = insertelement <vscale x 4 x float> [[INS_0]], float 0.000000e+00, i32 1 1563; CHECK-NEXT: [[INS_2:%.*]] = insertelement <vscale x 4 x float> [[INS_1]], float -9.000000e+00, i32 2 1564; CHECK-NEXT: [[INS_3:%.*]] = insertelement <vscale x 4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3 1565; CHECK-NEXT: ret <vscale x 4 x float> [[INS_3]] 1566; 1567 %ins.0 = insertelement <vscale x 4 x float> poison, float 1.0, i32 0 1568 %ins.1 = insertelement <vscale x 4 x float> %ins.0, float 0.0, i32 1 1569 %ins.2 = insertelement <vscale x 4 x float> %ins.1, float -9.0, i32 2 1570 %ins.3 = insertelement <vscale x 4 x float> %ins.2, float 0x7FF0000000000000, i32 3 1571 ret <vscale x 4 x float> %ins.3 1572} 1573 1574define <4 x float> @insertelement_unknown_base(<4 x float> %arg0) { 1575; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1576; CHECK-LABEL: define <4 x float> @insertelement_unknown_base 1577; CHECK-SAME: (<4 x float> [[ARG0:%.*]]) #[[ATTR3]] { 1578; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1 1579; CHECK-NEXT: ret <4 x float> [[INSERT]] 1580; 1581 %insert = insertelement <4 x float> %arg0, float 0.0, i32 1 1582 ret <4 x float> %insert 1583} 1584 1585define float @insertelement_extractelement_same(<4 x float> %arg0) { 1586; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1587; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @insertelement_extractelement_same 1588; CHECK-SAME: (<4 x float> [[ARG0:%.*]]) #[[ATTR3]] { 1589; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1 1590; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 1 1591; CHECK-NEXT: ret float [[EXTRACT]] 1592; 1593 %insert = insertelement <4 x float> %arg0, float 0.0, i32 1 1594 %extract = extractelement <4 x float> %insert, i32 1 1595 ret float %extract 1596} 1597 1598define float @insertelement_extractelement_different(<4 x float> nofpclass(zero) %arg0) { 1599; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1600; CHECK-LABEL: define nofpclass(zero) float @insertelement_extractelement_different 1601; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] { 1602; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1 1603; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 2 1604; CHECK-NEXT: ret float [[EXTRACT]] 1605; 1606 %insert = insertelement <4 x float> %arg0, float 0.0, i32 1 1607 %extract = extractelement <4 x float> %insert, i32 2 1608 ret float %extract 1609} 1610 1611define float @insertelement_extractelement_unknown(<4 x float> nofpclass(zero) %arg0, i32 %idx) { 1612; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1613; CHECK-LABEL: define nofpclass(nzero) float @insertelement_extractelement_unknown 1614; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] { 1615; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1 1616; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 [[IDX]] 1617; CHECK-NEXT: ret float [[EXTRACT]] 1618; 1619 %insert = insertelement <4 x float> %arg0, float 0.0, i32 1 1620 %extract = extractelement <4 x float> %insert, i32 %idx 1621 ret float %extract 1622} 1623 1624define <4 x float> @insertelement_index_oob_chain() { 1625; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1626; CHECK-LABEL: define nofpclass(nan ninf nzero sub norm) <4 x float> @insertelement_index_oob_chain 1627; CHECK-SAME: () #[[ATTR3]] { 1628; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4 1629; CHECK-NEXT: ret <4 x float> [[INSERT]] 1630; 1631 %insert = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4 1632 ret <4 x float> %insert 1633} 1634 1635define <2 x float> @multiple_extractelement(<4 x float> nofpclass(zero) %arg0) { 1636; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1637; CHECK-LABEL: define nofpclass(zero) <2 x float> @multiple_extractelement 1638; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] { 1639; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1 1640; CHECK-NEXT: [[EXTRACT2:%.*]] = extractelement <4 x float> [[INSERT]], i32 2 1641; CHECK-NEXT: [[EXTRACT3:%.*]] = extractelement <4 x float> [[INSERT]], i32 3 1642; CHECK-NEXT: [[INS_0:%.*]] = insertelement <2 x float> poison, float [[EXTRACT3]], i32 0 1643; CHECK-NEXT: [[INS_1:%.*]] = insertelement <2 x float> [[INS_0]], float [[EXTRACT2]], i32 1 1644; CHECK-NEXT: ret <2 x float> [[INS_1]] 1645; 1646 %insert = insertelement <4 x float> %arg0, float 0.0, i32 1 1647 %extract2 = extractelement <4 x float> %insert, i32 2 1648 %extract3 = extractelement <4 x float> %insert, i32 3 1649 %ins.0 = insertelement <2 x float> poison, float %extract3, i32 0 1650 %ins.1 = insertelement <2 x float> %ins.0, float %extract2, i32 1 1651 ret <2 x float> %ins.1 1652} 1653 1654; FIXME: Doesn't actually reach computeKnownFPClass 1655define <4 x float> @shufflevector_constexpr() { 1656; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1657; CHECK-LABEL: define <4 x float> @shufflevector_constexpr 1658; CHECK-SAME: () #[[ATTR3]] { 1659; CHECK-NEXT: ret <4 x float> <float 1.000000e+00, float bitcast (i32 ptrtoint (ptr @shufflevector_constexpr to i32) to float), float 4.000000e+00, float 0.000000e+00> 1660; 1661 ret <4 x float> shufflevector (<2 x float> <float 1.0, float bitcast (i32 ptrtoint (ptr @shufflevector_constexpr to i32) to float)>, <2 x float> <float 4.0, float 0.0>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>) 1662} 1663 1664define <4 x float> @shufflevector_concat_disjoint(<2 x float> nofpclass(nan) %arg0, <2 x float> nofpclass(inf) %arg1) { 1665; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1666; CHECK-LABEL: define <4 x float> @shufflevector_concat_disjoint 1667; CHECK-SAME: (<2 x float> nofpclass(nan) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1668; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1669; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1670; 1671 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1672 ret <4 x float> %shuffle 1673} 1674 1675define <4 x float> @shufflevector_concat_overlap(<2 x float> nofpclass(nan norm psub) %arg0, <2 x float> nofpclass(inf nan sub) %arg1) { 1676; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1677; CHECK-LABEL: define nofpclass(nan psub) <4 x float> @shufflevector_concat_overlap 1678; CHECK-SAME: (<2 x float> nofpclass(nan psub norm) [[ARG0:%.*]], <2 x float> nofpclass(nan inf sub) [[ARG1:%.*]]) #[[ATTR3]] { 1679; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1680; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1681; 1682 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1683 ret <4 x float> %shuffle 1684} 1685 1686define <4 x float> @shufflevector_unknown_lhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1687; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1688; CHECK-LABEL: define <4 x float> @shufflevector_unknown_lhs 1689; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1690; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1691; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1692; 1693 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1694 ret <4 x float> %shuffle 1695} 1696 1697define <4 x float> @shufflevector_unknown_rhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) { 1698; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1699; CHECK-LABEL: define <4 x float> @shufflevector_unknown_rhs 1700; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] { 1701; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1702; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1703; 1704 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1705 ret <4 x float> %shuffle 1706} 1707 1708define <4 x float> @shufflevector_unknown_all(<2 x float> %arg0, <2 x float> %arg1) { 1709; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1710; CHECK-LABEL: define <4 x float> @shufflevector_unknown_all 1711; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] { 1712; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1713; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1714; 1715 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1716 ret <4 x float> %shuffle 1717} 1718 1719define <4 x float> @shufflevector_only_demand_lhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) { 1720; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1721; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_lhs 1722; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] { 1723; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 1, i32 0> 1724; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1725; 1726 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 1, i32 0> 1727 ret <4 x float> %shuffle 1728} 1729 1730define <4 x float> @shufflevector_only_demand_rhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1731; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1732; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_rhs 1733; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1734; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 2, i32 3, i32 3, i32 2> 1735; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1736; 1737 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 2, i32 3, i32 3, i32 2> 1738 ret <4 x float> %shuffle 1739} 1740 1741define <4 x float> @shufflevector_undef_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1742; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1743; CHECK-LABEL: define <4 x float> @shufflevector_undef_demanded 1744; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1745; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> poison 1746; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1747; 1748 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> undef 1749 ret <4 x float> %shuffle 1750} 1751 1752define <4 x float> @shufflevector_zeroinit_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1753; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1754; CHECK-LABEL: define <4 x float> @shufflevector_zeroinit_demanded 1755; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1756; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> zeroinitializer 1757; CHECK-NEXT: ret <4 x float> [[SHUFFLE]] 1758; 1759 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> zeroinitializer 1760 ret <4 x float> %shuffle 1761} 1762 1763define float @shufflevector_extractelt0(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1764; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1765; CHECK-LABEL: define float @shufflevector_extractelt0 1766; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1767; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1768; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 0 1769; CHECK-NEXT: ret float [[EXTRACT]] 1770; 1771 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1772 %extract = extractelement <4 x float> %shuffle, i32 0 1773 ret float %extract 1774} 1775 1776define float @shufflevector_extractelt1(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1777; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1778; CHECK-LABEL: define nofpclass(inf) float @shufflevector_extractelt1 1779; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1780; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1781; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 1 1782; CHECK-NEXT: ret float [[EXTRACT]] 1783; 1784 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1785 %extract = extractelement <4 x float> %shuffle, i32 1 1786 ret float %extract 1787} 1788 1789define float @shufflevector_extractelt2(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1790; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1791; CHECK-LABEL: define float @shufflevector_extractelt2 1792; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1793; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1794; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 2 1795; CHECK-NEXT: ret float [[EXTRACT]] 1796; 1797 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1798 %extract = extractelement <4 x float> %shuffle, i32 2 1799 ret float %extract 1800} 1801 1802define float @shufflevector_extractelt3(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) { 1803; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1804; CHECK-LABEL: define float @shufflevector_extractelt3 1805; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] { 1806; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1807; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 3 1808; CHECK-NEXT: ret float [[EXTRACT]] 1809; 1810 %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1> 1811 %extract = extractelement <4 x float> %shuffle, i32 3 1812 ret float %extract 1813} 1814 1815define float @shufflevector_constantdatavector_demanded0() { 1816; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1817; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @shufflevector_constantdatavector_demanded0 1818; CHECK-SAME: () #[[ATTR3]] { 1819; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <3 x float> <float 1.000000e+00, float 0x7FF8000000000000, float 0.000000e+00>, <3 x float> poison, <2 x i32> <i32 0, i32 2> 1820; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[SHUFFLE]], i32 0 1821; CHECK-NEXT: ret float [[EXTRACT]] 1822; 1823 %shuffle = shufflevector <3 x float> <float 1.0, float 0x7FF8000000000000, float 0.0>, <3 x float> poison, <2 x i32> <i32 0, i32 2> 1824 %extract = extractelement <2 x float> %shuffle, i32 0 1825 ret float %extract 1826} 1827 1828define float @shufflevector_constantdatavector_demanded1() { 1829; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1830; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @shufflevector_constantdatavector_demanded1 1831; CHECK-SAME: () #[[ATTR3]] { 1832; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <3 x float> <float 1.000000e+00, float 0x7FF8000000000000, float 0.000000e+00>, <3 x float> poison, <2 x i32> <i32 0, i32 2> 1833; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[SHUFFLE]], i32 1 1834; CHECK-NEXT: ret float [[EXTRACT]] 1835; 1836 %shuffle = shufflevector <3 x float> <float 1.0, float 0x7FF8000000000000, float 0.0>, <3 x float> poison, <2 x i32> <i32 0, i32 2> 1837 %extract = extractelement <2 x float> %shuffle, i32 1 1838 ret float %extract 1839} 1840 1841define i32 @fptosi(float nofpclass(inf nan) %arg) { 1842; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1843; CHECK-LABEL: define i32 @fptosi 1844; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 1845; CHECK-NEXT: [[FPTOSI:%.*]] = fptosi float [[ARG]] to i32 1846; CHECK-NEXT: [[ADD:%.*]] = add i32 [[FPTOSI]], 1 1847; CHECK-NEXT: ret i32 [[ADD]] 1848; 1849 %fptosi = fptosi float %arg to i32 1850 %add = add i32 %fptosi, 1 1851 ret i32 %add 1852} 1853 1854define float @fptrunc(double nofpclass(inf nan) %arg) { 1855; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1856; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fptrunc 1857; CHECK-SAME: (double nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 1858; CHECK-NEXT: [[CAST:%.*]] = fptrunc double [[ARG]] to float 1859; CHECK-NEXT: [[MUL:%.*]] = fmul float [[CAST]], [[CAST]] 1860; CHECK-NEXT: ret float [[MUL]] 1861; 1862 %cast = fptrunc double %arg to float 1863 %mul = fmul float %cast, %cast 1864 ret float %mul 1865} 1866 1867define double @fpext(float nofpclass(inf nan) %arg) { 1868; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1869; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) double @fpext 1870; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 1871; CHECK-NEXT: [[CAST:%.*]] = fpext float [[ARG]] to double 1872; CHECK-NEXT: [[MUL:%.*]] = fmul double [[CAST]], [[CAST]] 1873; CHECK-NEXT: ret double [[MUL]] 1874; 1875 %cast = fpext float %arg to double 1876 %mul = fmul double %cast, %cast 1877 ret double %mul 1878} 1879 1880define float @atomicrmw_fadd(ptr %ptr, float nofpclass(inf nan) %val) { 1881; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) 1882; CHECK-LABEL: define float @atomicrmw_fadd 1883; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6:[0-9]+]] { 1884; CHECK-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr [[PTR]], float [[VAL]] seq_cst, align 4 1885; CHECK-NEXT: ret float [[RESULT]] 1886; 1887 %result = atomicrmw fadd ptr %ptr, float %val seq_cst 1888 ret float %result 1889} 1890 1891define float @load(ptr %ptr, float nofpclass(nan inf) %val) { 1892; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) 1893; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load 1894; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR7:[0-9]+]] { 1895; CHECK-NEXT: store float [[VAL]], ptr [[PTR]], align 4 1896; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR]], align 4 1897; CHECK-NEXT: [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]] 1898; CHECK-NEXT: ret float [[MUL]] 1899; 1900 store float %val, ptr %ptr 1901 %load = load float, ptr %ptr 1902 %mul = fmul float %load, %load 1903 ret float %mul 1904} 1905 1906define float @load_atomic(ptr %ptr, float nofpclass(nan inf) %val) { 1907; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) 1908; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load_atomic 1909; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6]] { 1910; CHECK-NEXT: store atomic float [[VAL]], ptr [[PTR]] seq_cst, align 4 1911; CHECK-NEXT: [[LOAD:%.*]] = load atomic float, ptr [[PTR]] seq_cst, align 4 1912; CHECK-NEXT: [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]] 1913; CHECK-NEXT: ret float [[MUL]] 1914; 1915 store atomic float %val, ptr %ptr seq_cst, align 4 1916 %load = load atomic float, ptr %ptr seq_cst, align 4 1917 %mul = fmul float %load, %load 1918 ret float %mul 1919} 1920 1921define <8 x float> @shufflevector_shufflevector(<4 x float> nofpclass(inf nan) %arg0, <4 x float> nofpclass(inf nan zero) %arg1) { 1922; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1923; CHECK-LABEL: define nofpclass(nan inf) <8 x float> @shufflevector_shufflevector 1924; CHECK-SAME: (<4 x float> nofpclass(nan inf) [[ARG0:%.*]], <4 x float> nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR3]] { 1925; CHECK-NEXT: [[SHUFFLE0:%.*]] = shufflevector <4 x float> [[ARG0]], <4 x float> [[ARG0]], <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1926; CHECK-NEXT: [[SHUFFLE1:%.*]] = shufflevector <4 x float> [[ARG1]], <4 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1927; CHECK-NEXT: [[SHUFFLE2:%.*]] = shufflevector <4 x float> [[SHUFFLE0]], <4 x float> [[SHUFFLE1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1928; CHECK-NEXT: ret <8 x float> [[SHUFFLE2]] 1929; 1930 %shuffle0 = shufflevector <4 x float> %arg0, <4 x float> %arg0, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 1931 %shuffle1 = shufflevector <4 x float> %arg1, <4 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1932 %shuffle2 = shufflevector <4 x float> %shuffle0, <4 x float> %shuffle1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1933 ret <8 x float> %shuffle2 1934} 1935 1936define float @constrained_sitofp(i32 %arg) strictfp { 1937; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) 1938; CHECK-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp 1939; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] { 1940; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR20]] 1941; CHECK-NEXT: ret float [[VAL]] 1942; 1943 %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") 1944 ret float %val 1945} 1946 1947define float @constrained_uitofp(i32 %arg) strictfp { 1948; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) 1949; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp 1950; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] { 1951; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR20]] 1952; CHECK-NEXT: ret float [[VAL]] 1953; 1954 %val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict") 1955 ret float %val 1956} 1957 1958define float @fadd_p0(float %arg0) { 1959; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1960; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0 1961; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 1962; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00 1963; CHECK-NEXT: ret float [[ADD]] 1964; 1965 %add = fadd float %arg0, 0.0 1966 ret float %add 1967} 1968 1969define float @fadd_n0(float %arg0) { 1970; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1971; CHECK-LABEL: define float @fadd_n0 1972; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 1973; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00 1974; CHECK-NEXT: ret float [[ADD]] 1975; 1976 %add = fadd float %arg0, -0.0 1977 ret float %add 1978} 1979 1980define float @fsub_p0(float %arg0) { 1981; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1982; CHECK-LABEL: define float @fsub_p0 1983; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 1984; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00 1985; CHECK-NEXT: ret float [[SUB]] 1986; 1987 %sub = fsub float %arg0, 0.0 1988 ret float %sub 1989} 1990 1991define float @fsub_n0(float %arg0) { 1992; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1993; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0 1994; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 1995; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00 1996; CHECK-NEXT: ret float [[SUB]] 1997; 1998 %sub = fsub float %arg0, -0.0 1999 ret float %sub 2000} 2001 2002define float @fsub_p0_commute(float %arg0) { 2003; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2004; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute 2005; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 2006; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]] 2007; CHECK-NEXT: ret float [[SUB]] 2008; 2009 %sub = fsub float 0.0, %arg0 2010 ret float %sub 2011} 2012 2013define float @fsub_n0_commute(float %arg0) { 2014; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2015; CHECK-LABEL: define float @fsub_n0_commute 2016; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] { 2017; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]] 2018; CHECK-NEXT: ret float [[SUB]] 2019; 2020 %sub = fsub float -0.0, %arg0 2021 ret float %sub 2022} 2023 2024define float @fadd_p0_ftz_daz(float %arg0) #3 { 2025; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2026; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ftz_daz 2027; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] { 2028; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00 2029; CHECK-NEXT: ret float [[ADD]] 2030; 2031 %add = fadd float %arg0, 0.0 2032 ret float %add 2033} 2034 2035define float @fadd_n0_ftz_daz(float %arg0) #0 { 2036; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2037; CHECK-LABEL: define float @fadd_n0_ftz_daz 2038; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10:[0-9]+]] { 2039; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00 2040; CHECK-NEXT: ret float [[ADD]] 2041; 2042 %add = fadd float %arg0, -0.0 2043 ret float %add 2044} 2045 2046define float @fsub_p0_ftz_daz(float %arg0) #0 { 2047; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2048; CHECK-LABEL: define float @fsub_p0_ftz_daz 2049; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] { 2050; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00 2051; CHECK-NEXT: ret float [[SUB]] 2052; 2053 %sub = fsub float %arg0, 0.0 2054 ret float %sub 2055} 2056 2057define float @fsub_n0_ftz_daz(float %arg0) #0 { 2058; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2059; CHECK-LABEL: define float @fsub_n0_ftz_daz 2060; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] { 2061; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00 2062; CHECK-NEXT: ret float [[SUB]] 2063; 2064 %sub = fsub float %arg0, -0.0 2065 ret float %sub 2066} 2067 2068define float @fsub_p0_commute_ftz_daz(float %arg0) #0 { 2069; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2070; CHECK-LABEL: define float @fsub_p0_commute_ftz_daz 2071; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] { 2072; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]] 2073; CHECK-NEXT: ret float [[SUB]] 2074; 2075 %sub = fsub float 0.0, %arg0 2076 ret float %sub 2077} 2078 2079define float @fsub_n0_commute_ftz_daz(float %arg0) #0 { 2080; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2081; CHECK-LABEL: define float @fsub_n0_commute_ftz_daz 2082; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] { 2083; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]] 2084; CHECK-NEXT: ret float [[SUB]] 2085; 2086 %sub = fsub float -0.0, %arg0 2087 ret float %sub 2088} 2089 2090define float @fadd_p0_ieee_daz(float %arg0) #2 { 2091; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2092; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ieee_daz 2093; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11:[0-9]+]] { 2094; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00 2095; CHECK-NEXT: ret float [[ADD]] 2096; 2097 %add = fadd float %arg0, 0.0 2098 ret float %add 2099} 2100 2101define float @fadd_p0_dapz_ieee(float %arg0) #4 { 2102; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2103; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_dapz_ieee 2104; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR12:[0-9]+]] { 2105; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00 2106; CHECK-NEXT: ret float [[ADD]] 2107; 2108 %add = fadd float %arg0, 0.0 2109 ret float %add 2110} 2111 2112define float @fadd_n0_ieee_daz(float %arg0) #2 { 2113; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2114; CHECK-LABEL: define float @fadd_n0_ieee_daz 2115; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] { 2116; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00 2117; CHECK-NEXT: ret float [[ADD]] 2118; 2119 %add = fadd float %arg0, -0.0 2120 ret float %add 2121} 2122 2123define float @fsub_p0_ieee_daz(float %arg0) #2 { 2124; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2125; CHECK-LABEL: define float @fsub_p0_ieee_daz 2126; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] { 2127; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00 2128; CHECK-NEXT: ret float [[SUB]] 2129; 2130 %sub = fsub float %arg0, 0.0 2131 ret float %sub 2132} 2133 2134define float @fsub_n0_ieee_daz(float %arg0) #2 { 2135; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2136; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0_ieee_daz 2137; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] { 2138; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00 2139; CHECK-NEXT: ret float [[SUB]] 2140; 2141 %sub = fsub float %arg0, -0.0 2142 ret float %sub 2143} 2144 2145define float @fsub_p0_commute_ieee_daz(float %arg0) #2 { 2146; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2147; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute_ieee_daz 2148; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] { 2149; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]] 2150; CHECK-NEXT: ret float [[SUB]] 2151; 2152 %sub = fsub float 0.0, %arg0 2153 ret float %sub 2154} 2155 2156define float @fsub_n0_commute_ieee_daz(float %arg0) #1 { 2157; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2158; CHECK-LABEL: define float @fsub_n0_commute_ieee_daz 2159; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR13:[0-9]+]] { 2160; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]] 2161; CHECK-NEXT: ret float [[SUB]] 2162; 2163 %sub = fsub float -0.0, %arg0 2164 ret float %sub 2165} 2166 2167define float @fadd_never_negzero_or_negsub(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) { 2168; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2169; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub 2170; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR3]] { 2171; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2172; CHECK-NEXT: ret float [[ADD]] 2173; 2174 %add = fadd float %a, %b 2175 ret float %add 2176} 2177 2178define float @fadd_never_negzero_or_negsub_daz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #2 { 2179; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2180; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_daz 2181; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR11]] { 2182; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2183; CHECK-NEXT: ret float [[ADD]] 2184; 2185 %add = fadd float %a, %b 2186 ret float %add 2187} 2188 2189define float @fadd_never_negzero_or_negsub_dapz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #5 { 2190; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2191; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_dapz 2192; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR14:[0-9]+]] { 2193; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2194; CHECK-NEXT: ret float [[ADD]] 2195; 2196 %add = fadd float %a, %b 2197 ret float %add 2198} 2199 2200define float @fadd_never_negzero_or_possub(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) { 2201; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2202; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub 2203; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR3]] { 2204; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2205; CHECK-NEXT: ret float [[ADD]] 2206; 2207 %add = fadd float %a, %b 2208 ret float %add 2209} 2210 2211define float @fadd_never_negzero_or_possub_daz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #2 { 2212; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2213; CHECK-LABEL: define float @fadd_never_negzero_or_possub_daz 2214; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR11]] { 2215; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2216; CHECK-NEXT: ret float [[ADD]] 2217; 2218 %add = fadd float %a, %b 2219 ret float %add 2220} 2221 2222define float @fadd_never_negzero_or_possub_dapz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #5 { 2223; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2224; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub_dapz 2225; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR14]] { 2226; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2227; CHECK-NEXT: ret float [[ADD]] 2228; 2229 %add = fadd float %a, %b 2230 ret float %add 2231} 2232 2233define float @fadd_never_negzero_or_sub_daz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #2 { 2234; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2235; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_daz 2236; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR11]] { 2237; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2238; CHECK-NEXT: ret float [[ADD]] 2239; 2240 %add = fadd float %a, %b 2241 ret float %add 2242} 2243 2244define float @fadd_never_negzero_or_sub_dapz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #5 { 2245; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2246; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_dapz 2247; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR14]] { 2248; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]] 2249; CHECK-NEXT: ret float [[ADD]] 2250; 2251 %add = fadd float %a, %b 2252 ret float %add 2253} 2254 2255define float @fadd_known_positive_lhs(float nofpclass(ninf nsub nnorm) %arg0, float %arg1) { 2256; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2257; CHECK-LABEL: define float @fadd_known_positive_lhs 2258; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] { 2259; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2260; CHECK-NEXT: ret float [[ADD]] 2261; 2262 %add = fadd float %arg0, %arg1 2263 ret float %add 2264} 2265 2266define float @fadd_known_positive_rhs(float %arg0, float nofpclass(ninf nsub nnorm) %arg1) { 2267; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2268; CHECK-LABEL: define float @fadd_known_positive_rhs 2269; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2270; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2271; CHECK-NEXT: ret float [[ADD]] 2272; 2273 %add = fadd float %arg0, %arg1 2274 ret float %add 2275} 2276 2277define float @fadd_known_positive(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) { 2278; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2279; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive 2280; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2281; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2282; CHECK-NEXT: ret float [[ADD]] 2283; 2284 %add = fadd float %arg0, %arg1 2285 ret float %add 2286} 2287 2288define float @fadd_known_positive_daz(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) #0 { 2289; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2290; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_daz 2291; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] { 2292; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2293; CHECK-NEXT: ret float [[ADD]] 2294; 2295 %add = fadd float %arg0, %arg1 2296 ret float %add 2297} 2298 2299define float @fadd_known_positive_nzero_lhs(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm) %arg1) { 2300; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2301; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_lhs 2302; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2303; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2304; CHECK-NEXT: ret float [[ADD]] 2305; 2306 %add = fadd float %arg0, %arg1 2307 ret float %add 2308} 2309 2310define float @fadd_known_positive_nzero_rhs(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) { 2311; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2312; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_rhs 2313; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2314; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2315; CHECK-NEXT: ret float [[ADD]] 2316; 2317 %add = fadd float %arg0, %arg1 2318 ret float %add 2319} 2320 2321define float @fadd_known_positive_nzero(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) { 2322; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2323; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero 2324; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2325; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2326; CHECK-NEXT: ret float [[ADD]] 2327; 2328 %add = fadd float %arg0, %arg1 2329 ret float %add 2330} 2331 2332define float @fadd_known_positive_nzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #0 { 2333; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2334; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz_daz 2335; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] { 2336; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2337; CHECK-NEXT: ret float [[ADD]] 2338; 2339 %add = fadd float %arg0, %arg1 2340 ret float %add 2341} 2342 2343define float @fadd_known_positive_nzero_ftz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #1 { 2344; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2345; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz 2346; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR13]] { 2347; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2348; CHECK-NEXT: ret float [[ADD]] 2349; 2350 %add = fadd float %arg0, %arg1 2351 ret float %add 2352} 2353 2354define float @fadd_known_positive_nzero_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #2 { 2355; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2356; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_daz 2357; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR11]] { 2358; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2359; CHECK-NEXT: ret float [[ADD]] 2360; 2361 %add = fadd float %arg0, %arg1 2362 ret float %add 2363} 2364 2365define float @fadd_known_positive_normal(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) { 2366; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2367; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal 2368; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR3]] { 2369; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2370; CHECK-NEXT: ret float [[ADD]] 2371; 2372 %add = fadd float %arg0, %arg1 2373 ret float %add 2374} 2375 2376define float @fadd_known_positive_normal_daz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #0 { 2377; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2378; CHECK-LABEL: define float @fadd_known_positive_normal_daz 2379; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR10]] { 2380; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2381; CHECK-NEXT: ret float [[ADD]] 2382; 2383 %add = fadd float %arg0, %arg1 2384 ret float %add 2385} 2386 2387define float @fadd_known_positive_normal_except0_daz(float nofpclass(ninf nnorm) %arg0, float nofpclass(ninf nnorm) %arg1) #0 { 2388; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2389; CHECK-LABEL: define float @fadd_known_positive_normal_except0_daz 2390; CHECK-SAME: (float nofpclass(ninf nnorm) [[ARG0:%.*]], float nofpclass(ninf nnorm) [[ARG1:%.*]]) #[[ATTR10]] { 2391; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2392; CHECK-NEXT: ret float [[ADD]] 2393; 2394 %add = fadd float %arg0, %arg1 2395 ret float %add 2396} 2397 2398define float @fadd_known_positive_normal_dapz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #3 { 2399; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2400; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal_dapz 2401; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR9]] { 2402; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]] 2403; CHECK-NEXT: ret float [[ADD]] 2404; 2405 %add = fadd float %arg0, %arg1 2406 ret float %add 2407} 2408 2409define internal float @returns_fence(float %arg) { 2410; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2411; TUNIT-LABEL: define internal float @returns_fence 2412; TUNIT-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 2413; TUNIT-NEXT: [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float nofpclass(inf) [[ARG]]) #[[ATTR22]] 2414; TUNIT-NEXT: ret float [[RET]] 2415; 2416; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2417; CGSCC-LABEL: define internal float @returns_fence 2418; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 2419; CGSCC-NEXT: [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]] 2420; CGSCC-NEXT: ret float [[RET]] 2421; 2422 %ret = call float @llvm.arithmetic.fence.f32(float %arg) 2423 ret float %ret 2424} 2425 2426; Check that the func0 callsite is marked with both no inf and no nan 2427define internal float @refine_callsite_attribute(float nofpclass(inf) %arg) { 2428; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2429; TUNIT-LABEL: define internal float @refine_callsite_attribute 2430; TUNIT-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] { 2431; TUNIT-NEXT: [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]] 2432; TUNIT-NEXT: [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR22]] 2433; TUNIT-NEXT: ret float [[RET]] 2434; 2435; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 2436; CGSCC-LABEL: define internal float @refine_callsite_attribute 2437; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR4]] { 2438; CGSCC-NEXT: [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]] 2439; CGSCC-NEXT: [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR19]] 2440; CGSCC-NEXT: ret float [[RET]] 2441; 2442 %func0 = call float @returns_fence(float nofpclass(nan) %arg) 2443 %ret = call float @llvm.arithmetic.fence.f32(float %func0) 2444 ret float %ret 2445} 2446 2447define float @user(float %arg) { 2448; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2449; TUNIT-LABEL: define float @user 2450; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { 2451; TUNIT-NEXT: [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(inf) [[ARG]]) #[[ATTR19]] 2452; TUNIT-NEXT: ret float [[FUNC1]] 2453; 2454; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 2455; CGSCC-LABEL: define float @user 2456; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR4]] { 2457; CGSCC-NEXT: [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]] 2458; CGSCC-NEXT: ret float [[FUNC1]] 2459; 2460 %func1 = call float @refine_callsite_attribute(float %arg) 2461 ret float %func1 2462} 2463 2464; value is passed through memory 2465define internal float @through_memory0(ptr %ptr.arg) { 2466; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2467; CGSCC-LABEL: define internal float @through_memory0 2468; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] { 2469; CGSCC-NEXT: [[PTR_ARG_PRIV:%.*]] = alloca float, align 4 2470; CGSCC-NEXT: store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4 2471; CGSCC-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4 2472; CGSCC-NEXT: ret float [[LOAD]] 2473; 2474 %load = load float, ptr %ptr.arg 2475 ret float %load 2476} 2477 2478; value is passed through memory and goes through an inferrable FP user 2479define internal float @through_memory1(ptr %ptr.arg) { 2480; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2481; TUNIT-LABEL: define internal float @through_memory1 2482; TUNIT-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] { 2483; TUNIT-NEXT: [[PTR_ARG_PRIV:%.*]] = alloca float, align 4 2484; TUNIT-NEXT: store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4 2485; TUNIT-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4 2486; TUNIT-NEXT: [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR22]] 2487; TUNIT-NEXT: ret float [[CALL]] 2488; 2489; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2490; CGSCC-LABEL: define internal float @through_memory1 2491; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] { 2492; CGSCC-NEXT: [[PTR_ARG_PRIV:%.*]] = alloca float, align 4 2493; CGSCC-NEXT: store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4 2494; CGSCC-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4 2495; CGSCC-NEXT: [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR19]] 2496; CGSCC-NEXT: ret float [[CALL]] 2497; 2498 %load = load float, ptr %ptr.arg 2499 %call = call float @llvm.arithmetic.fence.f32(float %load) 2500 ret float %call 2501} 2502 2503; value is passed through memory and goes through an uninferrable FP user 2504define internal float @through_memory2(ptr %ptr.arg) { 2505; CHECK: Function Attrs: memory(readwrite, argmem: none) 2506; CHECK-LABEL: define internal float @through_memory2 2507; CHECK-SAME: (float [[TMP0:%.*]]) #[[ATTR15:[0-9]+]] { 2508; CHECK-NEXT: [[PTR_ARG_PRIV:%.*]] = alloca float, align 4 2509; CHECK-NEXT: store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4 2510; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4 2511; CHECK-NEXT: [[CALL:%.*]] = call float @extern.f32(float [[LOAD]]) 2512; CHECK-NEXT: ret float [[CALL]] 2513; 2514 %load = load float, ptr %ptr.arg 2515 %call = call float @extern.f32(float %load) 2516 ret float %call 2517} 2518 2519define float @call_through_memory0(float nofpclass(nan) %val) { 2520; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2521; TUNIT-LABEL: define nofpclass(nan) float @call_through_memory0 2522; TUNIT-SAME: (float returned nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] { 2523; TUNIT-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2524; TUNIT-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2525; TUNIT-NEXT: ret float [[VAL]] 2526; 2527; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 2528; CGSCC-LABEL: define float @call_through_memory0 2529; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] { 2530; CGSCC-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2531; CGSCC-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2532; CGSCC-NEXT: [[THROUGH_MEMORY:%.*]] = call float @through_memory0(float nofpclass(nan) [[VAL]]) #[[ATTR19]] 2533; CGSCC-NEXT: ret float [[THROUGH_MEMORY]] 2534; 2535 %alloca = alloca float 2536 store float %val, ptr %alloca 2537 %through_memory = call float @through_memory0(ptr %alloca) 2538 ret float %through_memory 2539} 2540 2541define float @call_through_memory1(float nofpclass(nan) %val) { 2542; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2543; TUNIT-LABEL: define float @call_through_memory1 2544; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] { 2545; TUNIT-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2546; TUNIT-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2547; TUNIT-NEXT: [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4 2548; TUNIT-NEXT: [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float [[TMP1]]) #[[ATTR21]] 2549; TUNIT-NEXT: ret float [[THROUGH_MEMORY]] 2550; 2551; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 2552; CGSCC-LABEL: define float @call_through_memory1 2553; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] { 2554; CGSCC-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2555; CGSCC-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2556; CGSCC-NEXT: [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float nofpclass(nan) [[VAL]]) #[[ATTR19]] 2557; CGSCC-NEXT: ret float [[THROUGH_MEMORY]] 2558; 2559 %alloca = alloca float 2560 store float %val, ptr %alloca 2561 %through_memory = call float @through_memory1(ptr %alloca) 2562 ret float %through_memory 2563} 2564 2565define float @call_through_memory2(float nofpclass(nan) %val) { 2566; TUNIT-LABEL: define float @call_through_memory2 2567; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) { 2568; TUNIT-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2569; TUNIT-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2570; TUNIT-NEXT: [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4 2571; TUNIT-NEXT: [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float [[TMP1]]) 2572; TUNIT-NEXT: ret float [[THROUGH_MEMORY]] 2573; 2574; CGSCC-LABEL: define float @call_through_memory2 2575; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) { 2576; CGSCC-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 2577; CGSCC-NEXT: store float [[VAL]], ptr [[ALLOCA]], align 4 2578; CGSCC-NEXT: [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float nofpclass(nan) [[VAL]]) 2579; CGSCC-NEXT: ret float [[THROUGH_MEMORY]] 2580; 2581 %alloca = alloca float 2582 store float %val, ptr %alloca 2583 %through_memory = call float @through_memory2(ptr %alloca) 2584 ret float %through_memory 2585} 2586 2587define amdgpu_kernel void @fast_pow_kernel(ptr addrspace(1) nocapture noundef writeonly align 4 %out, ptr addrspace(1) nocapture noundef readonly align 4 %in1, ptr addrspace(1) nocapture noundef readonly align 4 %in2) { 2588; CHECK-LABEL: define amdgpu_kernel void @fast_pow_kernel 2589; CHECK-SAME: (ptr addrspace(1) nofree noundef writeonly align 4 captures(none) [[OUT:%.*]], ptr addrspace(1) nofree noundef readonly align 4 captures(none) [[IN1:%.*]], ptr addrspace(1) nofree noundef readonly align 4 captures(none) [[IN2:%.*]]) { 2590; CHECK-NEXT: entry: 2591; CHECK-NEXT: [[CALL:%.*]] = tail call i64 @_Z13get_global_idj(i32 noundef 0) 2592; CHECK-NEXT: [[SEXT:%.*]] = shl i64 [[CALL]], 32 2593; CHECK-NEXT: [[IDXPROM:%.*]] = ashr exact i64 [[SEXT]], 32 2594; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN1]], i64 [[IDXPROM]] 2595; CHECK-NEXT: [[I:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX]], align 4 2596; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN2]], i64 [[IDXPROM]] 2597; CHECK-NEXT: [[I1:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX2]], align 4 2598; CHECK-NEXT: [[CALL3:%.*]] = tail call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) float @pow_wrapper(float noundef nofpclass(nan inf) [[I]], float noundef nofpclass(nan inf) [[I1]]) 2599; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[OUT]], i64 [[IDXPROM]] 2600; CHECK-NEXT: store float [[CALL3]], ptr addrspace(1) [[ARRAYIDX5]], align 4 2601; CHECK-NEXT: ret void 2602; 2603entry: 2604 %call = tail call i64 @_Z13get_global_idj(i32 noundef 0) 2605 %sext = shl i64 %call, 32 2606 %idxprom = ashr exact i64 %sext, 32 2607 %arrayidx = getelementptr inbounds float, ptr addrspace(1) %in1, i64 %idxprom 2608 %i = load float, ptr addrspace(1) %arrayidx, align 4 2609 %arrayidx2 = getelementptr inbounds float, ptr addrspace(1) %in2, i64 %idxprom 2610 %i1 = load float, ptr addrspace(1) %arrayidx2, align 4 2611 %call3 = tail call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) float @pow_wrapper(float noundef nofpclass(nan inf) %i, float noundef nofpclass(nan inf) %i1) 2612 %arrayidx5 = getelementptr inbounds float, ptr addrspace(1) %out, i64 %idxprom 2613 store float %call3, ptr addrspace(1) %arrayidx5, align 4 2614 ret void 2615} 2616 2617define internal float @pow_wrapper(float %arg, float %arg1) { 2618; TUNIT: Function Attrs: norecurse 2619; TUNIT-LABEL: define internal float @pow_wrapper 2620; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] { 2621; TUNIT-NEXT: bb: 2622; TUNIT-NEXT: [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]]) 2623; TUNIT-NEXT: ret float [[I]] 2624; 2625; CGSCC-LABEL: define internal float @pow_wrapper 2626; CGSCC-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) { 2627; CGSCC-NEXT: bb: 2628; CGSCC-NEXT: [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]]) 2629; CGSCC-NEXT: ret float [[I]] 2630; 2631bb: 2632 %i = tail call float @pow_impl(float %arg, float %arg1) 2633 ret float %i 2634} 2635 2636; nofpclass(nan inf) should reach here through pow_wrapper 2637define internal float @pow_impl(float %arg, float %arg1) { 2638; TUNIT: Function Attrs: norecurse 2639; TUNIT-LABEL: define internal float @pow_impl 2640; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16]] { 2641; TUNIT-NEXT: bb: 2642; TUNIT-NEXT: [[IMPLEMENT_POW:%.*]] = call float asm " 2643; TUNIT-NEXT: ret float [[IMPLEMENT_POW]] 2644; 2645; CGSCC: Function Attrs: norecurse 2646; CGSCC-LABEL: define internal float @pow_impl 2647; CGSCC-SAME: (float [[ARG:%.*]], float [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] { 2648; CGSCC-NEXT: bb: 2649; CGSCC-NEXT: [[IMPLEMENT_POW:%.*]] = call float asm " 2650; CGSCC-NEXT: ret float [[IMPLEMENT_POW]] 2651; 2652bb: 2653 %implement.pow = call float asm " ; do pow $0, $1, $2", "=v,v,v"(float %arg, float %arg1) 2654 ret float %implement.pow 2655} 2656 2657define [4 x float] @constant_aggregate_zero() { 2658; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2659; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) [4 x float] @constant_aggregate_zero 2660; CHECK-SAME: () #[[ATTR3]] { 2661; CHECK-NEXT: ret [4 x float] zeroinitializer 2662; 2663 ret [4 x float] zeroinitializer 2664} 2665 2666define <vscale x 4 x float> @scalable_splat_pnorm() { 2667; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2668; CHECK-LABEL: define <vscale x 4 x float> @scalable_splat_pnorm 2669; CHECK-SAME: () #[[ATTR3]] { 2670; CHECK-NEXT: ret <vscale x 4 x float> splat (float 1.000000e+00) 2671; 2672 ret <vscale x 4 x float> splat (float 1.0) 2673} 2674 2675define <vscale x 4 x float> @scalable_splat_zero() { 2676; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2677; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <vscale x 4 x float> @scalable_splat_zero 2678; CHECK-SAME: () #[[ATTR3]] { 2679; CHECK-NEXT: ret <vscale x 4 x float> zeroinitializer 2680; 2681 ret <vscale x 4 x float> zeroinitializer 2682} 2683 2684; Verify we do not derive 'nofpclass(inf zero sub norm)' for the argument __x. 2685; See https://github.com/llvm/llvm-project/issues/78507 2686 2687define double @call_abs(double noundef %__x) { 2688; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2689; TUNIT-LABEL: define noundef nofpclass(ninf nzero nsub nnorm) double @call_abs 2690; TUNIT-SAME: (double noundef [[__X:%.*]]) #[[ATTR3]] { 2691; TUNIT-NEXT: entry: 2692; TUNIT-NEXT: [[ABS:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) double @llvm.fabs.f64(double noundef [[__X]]) #[[ATTR22]] 2693; TUNIT-NEXT: ret double [[ABS]] 2694; 2695; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2696; CGSCC-LABEL: define noundef nofpclass(ninf nzero nsub nnorm) double @call_abs 2697; CGSCC-SAME: (double noundef [[__X:%.*]]) #[[ATTR3]] { 2698; CGSCC-NEXT: entry: 2699; CGSCC-NEXT: [[ABS:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) double @llvm.fabs.f64(double noundef [[__X]]) #[[ATTR19]] 2700; CGSCC-NEXT: ret double [[ABS]] 2701; 2702entry: 2703 %abs = tail call double @llvm.fabs.f64(double %__x) 2704 ret double %abs 2705} 2706 2707define float @bitcast_to_float_sign_0(i32 %arg) { 2708; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2709; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @bitcast_to_float_sign_0 2710; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2711; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[ARG]], 1 2712; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[SHR]] to float 2713; CHECK-NEXT: ret float [[CAST]] 2714; 2715 %shr = lshr i32 %arg, 1 2716 %cast = bitcast i32 %shr to float 2717 ret float %cast 2718} 2719 2720define float @bitcast_to_float_nnan(i32 %arg) { 2721; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2722; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @bitcast_to_float_nnan 2723; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2724; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[ARG]], 2 2725; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[SHR]] to float 2726; CHECK-NEXT: ret float [[CAST]] 2727; 2728 %shr = lshr i32 %arg, 2 2729 %cast = bitcast i32 %shr to float 2730 ret float %cast 2731} 2732 2733define float @bitcast_to_float_sign_1(i32 %arg) { 2734; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2735; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @bitcast_to_float_sign_1 2736; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2737; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG]], -2147483648 2738; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[OR]] to float 2739; CHECK-NEXT: ret float [[CAST]] 2740; 2741 %or = or i32 %arg, -2147483648 2742 %cast = bitcast i32 %or to float 2743 ret float %cast 2744} 2745 2746define float @bitcast_to_float_nan(i32 %arg) { 2747; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2748; CHECK-LABEL: define nofpclass(inf zero sub norm) float @bitcast_to_float_nan 2749; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2750; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG]], 2139095041 2751; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[OR]] to float 2752; CHECK-NEXT: ret float [[CAST]] 2753; 2754 %or = or i32 %arg, 2139095041 2755 %cast = bitcast i32 %or to float 2756 ret float %cast 2757} 2758 2759define float @bitcast_to_float_zero(i32 %arg) { 2760; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2761; CHECK-LABEL: define nofpclass(nan inf sub norm) float @bitcast_to_float_zero 2762; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2763; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ARG]], 31 2764; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[SHL]] to float 2765; CHECK-NEXT: ret float [[CAST]] 2766; 2767 %shl = shl i32 %arg, 31 2768 %cast = bitcast i32 %shl to float 2769 ret float %cast 2770} 2771 2772define float @bitcast_to_float_nzero(i32 %arg) { 2773; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2774; CHECK-LABEL: define nofpclass(zero) float @bitcast_to_float_nzero 2775; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2776; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG]], 134217728 2777; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[OR]] to float 2778; CHECK-NEXT: ret float [[CAST]] 2779; 2780 %or = or i32 %arg, 134217728 2781 %cast = bitcast i32 %or to float 2782 ret float %cast 2783} 2784 2785define float @bitcast_to_float_inf(i32 %arg) { 2786; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2787; CHECK-LABEL: define nofpclass(nan zero sub norm) float @bitcast_to_float_inf 2788; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { 2789; CHECK-NEXT: [[SHR:%.*]] = shl i32 [[ARG]], 31 2790; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHR]], 2139095040 2791; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 [[OR]] to float 2792; CHECK-NEXT: ret float [[CAST]] 2793; 2794 %shr = shl i32 %arg, 31 2795 %or = or i32 %shr, 2139095040 2796 %cast = bitcast i32 %or to float 2797 ret float %cast 2798} 2799 2800define double @bitcast_to_double_sign_0(i64 %arg) { 2801; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2802; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) double @bitcast_to_double_sign_0 2803; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2804; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[ARG]], 1 2805; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[SHR]] to double 2806; CHECK-NEXT: ret double [[CAST]] 2807; 2808 %shr = lshr i64 %arg, 1 2809 %cast = bitcast i64 %shr to double 2810 ret double %cast 2811} 2812 2813define double @bitcast_to_double_nnan(i64 %arg) { 2814; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2815; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) double @bitcast_to_double_nnan 2816; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2817; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[ARG]], 2 2818; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[SHR]] to double 2819; CHECK-NEXT: ret double [[CAST]] 2820; 2821 %shr = lshr i64 %arg, 2 2822 %cast = bitcast i64 %shr to double 2823 ret double %cast 2824} 2825 2826define double @bitcast_to_double_sign_1(i64 %arg) { 2827; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2828; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) double @bitcast_to_double_sign_1 2829; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2830; CHECK-NEXT: [[OR:%.*]] = or i64 [[ARG]], -9223372036854775808 2831; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[OR]] to double 2832; CHECK-NEXT: ret double [[CAST]] 2833; 2834 %or = or i64 %arg, -9223372036854775808 2835 %cast = bitcast i64 %or to double 2836 ret double %cast 2837} 2838 2839define double @bitcast_to_double_nan(i64 %arg) { 2840; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2841; CHECK-LABEL: define nofpclass(inf zero sub norm) double @bitcast_to_double_nan 2842; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2843; CHECK-NEXT: [[OR:%.*]] = or i64 [[ARG]], -4503599627370495 2844; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[OR]] to double 2845; CHECK-NEXT: ret double [[CAST]] 2846; 2847 %or = or i64 %arg, -4503599627370495 2848 %cast = bitcast i64 %or to double 2849 ret double %cast 2850} 2851 2852 2853define double @bitcast_to_double_zero(i64 %arg) { 2854; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2855; CHECK-LABEL: define nofpclass(nan inf sub norm) double @bitcast_to_double_zero 2856; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2857; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ARG]], 63 2858; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[SHL]] to double 2859; CHECK-NEXT: ret double [[CAST]] 2860; 2861 %shl = shl i64 %arg, 63 2862 %cast = bitcast i64 %shl to double 2863 ret double %cast 2864} 2865 2866define double @bitcast_to_double_nzero(i64 %arg) { 2867; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2868; CHECK-LABEL: define nofpclass(zero) double @bitcast_to_double_nzero 2869; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2870; CHECK-NEXT: [[OR:%.*]] = or i64 [[ARG]], 1152921504606846976 2871; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[OR]] to double 2872; CHECK-NEXT: ret double [[CAST]] 2873; 2874 %or = or i64 %arg, 1152921504606846976 2875 %cast = bitcast i64 %or to double 2876 ret double %cast 2877} 2878 2879define double @bitcast_to_double_inf(i64 %arg) { 2880; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2881; CHECK-LABEL: define nofpclass(nan zero sub norm) double @bitcast_to_double_inf 2882; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] { 2883; CHECK-NEXT: [[SHR:%.*]] = shl i64 [[ARG]], 63 2884; CHECK-NEXT: [[OR:%.*]] = or i64 [[SHR]], 9218868437227405312 2885; CHECK-NEXT: [[CAST:%.*]] = bitcast i64 [[OR]] to double 2886; CHECK-NEXT: ret double [[CAST]] 2887; 2888 %shr = shl i64 %arg, 63 2889 %or = or i64 %shr, 9218868437227405312 2890 %cast = bitcast i64 %or to double 2891 ret double %cast 2892} 2893 2894 2895define <2 x float> @bitcast_to_float_vect_sign_0(<2 x i32> %arg) { 2896; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2897; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) <2 x float> @bitcast_to_float_vect_sign_0 2898; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2899; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[ARG]], <i32 1, i32 2> 2900; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[SHR]] to <2 x float> 2901; CHECK-NEXT: ret <2 x float> [[CAST]] 2902; 2903 %shr = lshr <2 x i32> %arg, <i32 1, i32 2> 2904 %cast = bitcast <2 x i32> %shr to <2 x float> 2905 ret <2 x float> %cast 2906} 2907 2908define <2 x float> @bitcast_to_float_vect_nnan(<2 x i32> %arg) { 2909; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2910; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) <2 x float> @bitcast_to_float_vect_nnan 2911; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2912; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[ARG]], splat (i32 4) 2913; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[SHR]] to <2 x float> 2914; CHECK-NEXT: ret <2 x float> [[CAST]] 2915; 2916 %shr = lshr <2 x i32> %arg, <i32 4, i32 4> 2917 %cast = bitcast <2 x i32> %shr to <2 x float> 2918 ret <2 x float> %cast 2919} 2920 2921define <2 x float> @bitcast_to_float_vect_sign_1(<2 x i32> %arg) { 2922; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2923; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) <2 x float> @bitcast_to_float_vect_sign_1 2924; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2925; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[ARG]], splat (i32 -2147483648) 2926; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float> 2927; CHECK-NEXT: ret <2 x float> [[CAST]] 2928; 2929 %or = or <2 x i32> %arg, <i32 -2147483648, i32 -2147483648> 2930 %cast = bitcast <2 x i32> %or to <2 x float> 2931 ret <2 x float> %cast 2932} 2933 2934define <2 x float> @bitcast_to_float_vect_nan(<2 x i32> %arg) { 2935; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2936; CHECK-LABEL: define nofpclass(inf zero sub norm) <2 x float> @bitcast_to_float_vect_nan 2937; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2938; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[ARG]], splat (i32 2139095041) 2939; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float> 2940; CHECK-NEXT: ret <2 x float> [[CAST]] 2941; 2942 %or = or <2 x i32> %arg, <i32 2139095041, i32 2139095041> 2943 %cast = bitcast <2 x i32> %or to <2 x float> 2944 ret <2 x float> %cast 2945} 2946 2947define <2 x float> @bitcast_to_float_vect_conservative_1(<2 x i32> %arg) { 2948; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2949; CHECK-LABEL: define <2 x float> @bitcast_to_float_vect_conservative_1 2950; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2951; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[ARG]], <i32 -2147483648, i32 0> 2952; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float> 2953; CHECK-NEXT: ret <2 x float> [[CAST]] 2954; 2955 %or = or <2 x i32> %arg, <i32 -2147483648, i32 0> 2956 %cast = bitcast <2 x i32> %or to <2 x float> 2957 ret <2 x float> %cast 2958} 2959 2960define <2 x float> @bitcast_to_float_vect_conservative_2(<2 x i32> %arg) { 2961; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 2962; CHECK-LABEL: define <2 x float> @bitcast_to_float_vect_conservative_2 2963; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] { 2964; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[ARG]], <i32 0, i32 2139095041> 2965; CHECK-NEXT: [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float> 2966; CHECK-NEXT: ret <2 x float> [[CAST]] 2967; 2968 %or = or <2 x i32> %arg, <i32 0, i32 2139095041> 2969 %cast = bitcast <2 x i32> %or to <2 x float> 2970 ret <2 x float> %cast 2971} 2972 2973declare i64 @_Z13get_global_idj(i32 noundef) 2974 2975attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" } 2976attributes #1 = { "denormal-fp-math"="preserve-sign,ieee" } 2977attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" } 2978attributes #3 = { "denormal-fp-math"="positive-zero,positive-zero" } 2979attributes #4 = { "denormal-fp-math"="positive-zero,ieee" } 2980attributes #5 = { "denormal-fp-math"="ieee,positive-zero" } 2981