1; RUN: opt < %s -passes=inline -S | FileCheck %s 2; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s 3target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" 4 5define i32 @noattr_callee(i32 %i) { 6 ret i32 %i 7} 8 9define i32 @sanitize_address_callee(i32 %i) sanitize_address { 10 ret i32 %i 11} 12 13define i32 @sanitize_hwaddress_callee(i32 %i) sanitize_hwaddress { 14 ret i32 %i 15} 16 17define i32 @sanitize_thread_callee(i32 %i) sanitize_thread { 18 ret i32 %i 19} 20 21define i32 @sanitize_memory_callee(i32 %i) sanitize_memory { 22 ret i32 %i 23} 24 25define i32 @sanitize_memtag_callee(i32 %i) sanitize_memtag { 26 ret i32 %i 27} 28 29define i32 @safestack_callee(i32 %i) safestack { 30 ret i32 %i 31} 32 33define i32 @slh_callee(i32 %i) speculative_load_hardening { 34 ret i32 %i 35} 36 37define i32 @alwaysinline_callee(i32 %i) alwaysinline { 38 ret i32 %i 39} 40 41define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address { 42 ret i32 %i 43} 44 45define i32 @alwaysinline_sanitize_hwaddress_callee(i32 %i) alwaysinline sanitize_hwaddress { 46 ret i32 %i 47} 48 49define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread { 50 ret i32 %i 51} 52 53define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory { 54 ret i32 %i 55} 56 57define i32 @alwaysinline_sanitize_memtag_callee(i32 %i) alwaysinline sanitize_memtag { 58 ret i32 %i 59} 60 61define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack { 62 ret i32 %i 63} 64 65 66; Check that: 67; * noattr callee is inlined into noattr caller, 68; * sanitize_(address|memory|thread) callee is not inlined into noattr caller, 69; * alwaysinline callee is always inlined no matter what sanitize_* attributes are present. 70 71define i32 @test_no_sanitize_address(i32 %arg) { 72 %x1 = call i32 @noattr_callee(i32 %arg) 73 %x2 = call i32 @sanitize_address_callee(i32 %x1) 74 %x3 = call i32 @alwaysinline_callee(i32 %x2) 75 %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3) 76 ret i32 %x4 77; CHECK-LABEL: @test_no_sanitize_address( 78; CHECK-NEXT: @sanitize_address_callee 79; CHECK-NEXT: ret i32 80} 81 82define i32 @test_no_sanitize_hwaddress(i32 %arg) { 83 %x1 = call i32 @noattr_callee(i32 %arg) 84 %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1) 85 %x3 = call i32 @alwaysinline_callee(i32 %x2) 86 %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3) 87 ret i32 %x4 88; CHECK-LABEL: @test_no_sanitize_hwaddress( 89; CHECK-NEXT: @sanitize_hwaddress_callee 90; CHECK-NEXT: ret i32 91} 92 93define i32 @test_no_sanitize_memory(i32 %arg) { 94 %x1 = call i32 @noattr_callee(i32 %arg) 95 %x2 = call i32 @sanitize_memory_callee(i32 %x1) 96 %x3 = call i32 @alwaysinline_callee(i32 %x2) 97 %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3) 98 ret i32 %x4 99; CHECK-LABEL: @test_no_sanitize_memory( 100; CHECK-NEXT: @sanitize_memory_callee 101; CHECK-NEXT: ret i32 102} 103 104define i32 @test_no_sanitize_thread(i32 %arg) { 105 %x1 = call i32 @noattr_callee(i32 %arg) 106 %x2 = call i32 @sanitize_thread_callee(i32 %x1) 107 %x3 = call i32 @alwaysinline_callee(i32 %x2) 108 %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3) 109 ret i32 %x4 110; CHECK-LABEL: @test_no_sanitize_thread( 111; CHECK-NEXT: @sanitize_thread_callee 112; CHECK-NEXT: ret i32 113} 114 115define i32 @test_no_sanitize_memtag(i32 %arg) { 116 %x1 = call i32 @noattr_callee(i32 %arg) 117 %x2 = call i32 @sanitize_memtag_callee(i32 %x1) 118 %x3 = call i32 @alwaysinline_callee(i32 %x2) 119 %x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3) 120 ret i32 %x4 121; CHECK-LABEL: @test_no_sanitize_memtag( 122; CHECK-NEXT: @sanitize_memtag_callee 123; CHECK-NEXT: ret i32 124} 125 126 127; Check that: 128; * noattr callee is not inlined into sanitize_(address|memory|thread) caller, 129; * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute, 130; * alwaysinline callee is always inlined no matter what sanitize_* attributes are present. 131 132define i32 @test_sanitize_address(i32 %arg) sanitize_address { 133 %x1 = call i32 @noattr_callee(i32 %arg) 134 %x2 = call i32 @sanitize_address_callee(i32 %x1) 135 %x3 = call i32 @alwaysinline_callee(i32 %x2) 136 %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3) 137 ret i32 %x4 138; CHECK-LABEL: @test_sanitize_address( 139; CHECK-NEXT: @noattr_callee 140; CHECK-NEXT: ret i32 141} 142 143define i32 @test_sanitize_hwaddress(i32 %arg) sanitize_hwaddress { 144 %x1 = call i32 @noattr_callee(i32 %arg) 145 %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1) 146 %x3 = call i32 @alwaysinline_callee(i32 %x2) 147 %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3) 148 ret i32 %x4 149; CHECK-LABEL: @test_sanitize_hwaddress( 150; CHECK-NEXT: @noattr_callee 151; CHECK-NEXT: ret i32 152} 153 154define i32 @test_sanitize_memory(i32 %arg) sanitize_memory { 155 %x1 = call i32 @noattr_callee(i32 %arg) 156 %x2 = call i32 @sanitize_memory_callee(i32 %x1) 157 %x3 = call i32 @alwaysinline_callee(i32 %x2) 158 %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3) 159 ret i32 %x4 160; CHECK-LABEL: @test_sanitize_memory( 161; CHECK-NEXT: @noattr_callee 162; CHECK-NEXT: ret i32 163} 164 165define i32 @test_sanitize_thread(i32 %arg) sanitize_thread { 166 %x1 = call i32 @noattr_callee(i32 %arg) 167 %x2 = call i32 @sanitize_thread_callee(i32 %x1) 168 %x3 = call i32 @alwaysinline_callee(i32 %x2) 169 %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3) 170 ret i32 %x4 171; CHECK-LABEL: @test_sanitize_thread( 172; CHECK-NEXT: @noattr_callee 173; CHECK-NEXT: ret i32 174} 175 176define i32 @test_sanitize_memtag(i32 %arg) sanitize_memtag { 177 %x1 = call i32 @noattr_callee(i32 %arg) 178 %x2 = call i32 @sanitize_memtag_callee(i32 %x1) 179 %x3 = call i32 @alwaysinline_callee(i32 %x2) 180 %x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3) 181 ret i32 %x4 182; CHECK-LABEL: @test_sanitize_memtag( 183; CHECK-NEXT: @noattr_callee 184; CHECK-NEXT: ret i32 185} 186 187define i32 @test_safestack(i32 %arg) safestack { 188 %x1 = call i32 @noattr_callee(i32 %arg) 189 %x2 = call i32 @safestack_callee(i32 %x1) 190 %x3 = call i32 @alwaysinline_callee(i32 %x2) 191 %x4 = call i32 @alwaysinline_safestack_callee(i32 %x3) 192 ret i32 %x4 193; CHECK-LABEL: @test_safestack( 194; CHECK-NEXT: @noattr_callee 195; CHECK-NEXT: ret i32 196} 197 198; Can inline a normal function into an SLH'ed function. 199define i32 @test_caller_slh(i32 %i) speculative_load_hardening { 200; CHECK-LABEL: @test_caller_slh( 201; CHECK-SAME: ) [[SLH:.*]] { 202; CHECK-NOT: call 203; CHECK: ret i32 204entry: 205 %callee = call i32 @noattr_callee(i32 %i) 206 ret i32 %callee 207} 208 209; Can inline a SLH'ed function into a normal one, propagating SLH. 210define i32 @test_callee_slh(i32 %i) { 211; CHECK-LABEL: @test_callee_slh( 212; CHECK-SAME: ) [[SLH:.*]] { 213; CHECK-NOT: call 214; CHECK: ret i32 215entry: 216 %callee = call i32 @slh_callee(i32 %i) 217 ret i32 %callee 218} 219 220; Check that a function doesn't get inlined if target-cpu strings don't match 221; exactly. 222define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" { 223 ret i32 %i 224} 225 226define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" { 227 %1 = call i32 @test_target_cpu_callee0(i32 %i) 228 ret i32 %1 229; CHECK-LABEL: @test_target_cpu0( 230; CHECK-NOT: @test_target_cpu_callee0 231} 232 233define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" { 234 ret i32 %i 235} 236 237define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" { 238 %1 = call i32 @test_target_cpu_callee1(i32 %i) 239 ret i32 %1 240; CHECK-LABEL: @test_target_cpu1( 241; CHECK-NEXT: @test_target_cpu_callee1 242; CHECK-NEXT: ret i32 243} 244 245; Check that a function doesn't get inlined if target-features strings don't 246; match exactly. 247define i32 @test_target_features_callee0(i32 %i) "target-features"="+sse4.2" { 248 ret i32 %i 249} 250 251define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" { 252 %1 = call i32 @test_target_features_callee0(i32 %i) 253 ret i32 %1 254; CHECK-LABEL: @test_target_features0( 255; CHECK-NOT: @test_target_features_callee0 256} 257 258define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" { 259 ret i32 %i 260} 261 262define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" { 263 %1 = call i32 @test_target_features_callee1(i32 %i) 264 ret i32 %1 265; CHECK-LABEL: @test_target_features1( 266; CHECK-NEXT: @test_target_features_callee1 267; CHECK-NEXT: ret i32 268} 269 270define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" { 271 ret i32 %i 272; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] { 273; CHECK-NEXT: ret i32 274} 275 276define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" { 277 ret i32 %i 278; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] { 279; CHECK-NEXT: ret i32 280} 281 282define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" { 283 %1 = call i32 @less-precise-fpmad_callee0(i32 %i) 284 ret i32 %1 285; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] { 286; CHECK-NEXT: ret i32 287} 288 289define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" { 290 %1 = call i32 @less-precise-fpmad_callee1(i32 %i) 291 ret i32 %1 292; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] { 293; CHECK-NEXT: ret i32 294} 295 296define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" { 297 %1 = call i32 @less-precise-fpmad_callee0(i32 %i) 298 ret i32 %1 299; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] { 300; CHECK-NEXT: ret i32 301} 302 303define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" { 304 %1 = call i32 @less-precise-fpmad_callee1(i32 %i) 305 ret i32 %1 306; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] { 307; CHECK-NEXT: ret i32 308} 309 310define i32 @no-implicit-float_callee0(i32 %i) { 311 ret i32 %i 312; CHECK: @no-implicit-float_callee0(i32 %i) { 313; CHECK-NEXT: ret i32 314} 315 316define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat { 317 ret i32 %i 318; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] { 319; CHECK-NEXT: ret i32 320} 321 322define i32 @test_no-implicit-float0(i32 %i) { 323 %1 = call i32 @no-implicit-float_callee0(i32 %i) 324 ret i32 %1 325; CHECK: @test_no-implicit-float0(i32 %i) { 326; CHECK-NEXT: ret i32 327} 328 329define i32 @test_no-implicit-float1(i32 %i) { 330 %1 = call i32 @no-implicit-float_callee1(i32 %i) 331 ret i32 %1 332; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] { 333; CHECK-NEXT: ret i32 334} 335 336define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat { 337 %1 = call i32 @no-implicit-float_callee0(i32 %i) 338 ret i32 %1 339; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] { 340; CHECK-NEXT: ret i32 341} 342 343define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat { 344 %1 = call i32 @no-implicit-float_callee1(i32 %i) 345 ret i32 %1 346; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] { 347; CHECK-NEXT: ret i32 348} 349 350; Check that no-jump-tables flag propagates from inlined callee to caller 351 352define i32 @no-use-jump-tables_callee0(i32 %i) { 353 ret i32 %i 354; CHECK: @no-use-jump-tables_callee0(i32 %i) { 355; CHECK-NEXT: ret i32 356} 357 358define i32 @no-use-jump-tables_callee1(i32 %i) "no-jump-tables"="true" { 359 ret i32 %i 360; CHECK: @no-use-jump-tables_callee1(i32 %i) [[NOUSEJUMPTABLES:#[0-9]+]] { 361; CHECK-NEXT: ret i32 362} 363 364define i32 @test_no-use-jump-tables0(i32 %i) { 365 %1 = call i32 @no-use-jump-tables_callee0(i32 %i) 366 ret i32 %1 367; CHECK: @test_no-use-jump-tables0(i32 %i) { 368; CHECK-NEXT: ret i32 369} 370 371define i32 @test_no-use-jump-tables1(i32 %i) { 372 %1 = call i32 @no-use-jump-tables_callee1(i32 %i) 373 ret i32 %1 374; CHECK: @test_no-use-jump-tables1(i32 %i) [[NOUSEJUMPTABLES]] { 375; CHECK-NEXT: ret i32 376} 377 378define i32 @test_no-use-jump-tables2(i32 %i) "no-jump-tables"="true" { 379 %1 = call i32 @no-use-jump-tables_callee0(i32 %i) 380 ret i32 %1 381; CHECK: @test_no-use-jump-tables2(i32 %i) [[NOUSEJUMPTABLES]] { 382; CHECK-NEXT: ret i32 383} 384 385define i32 @test_no-use-jump-tables3(i32 %i) "no-jump-tables"="true" { 386 %1 = call i32 @no-use-jump-tables_callee1(i32 %i) 387 ret i32 %1 388; CHECK: @test_no-use-jump-tables3(i32 %i) [[NOUSEJUMPTABLES]] { 389; CHECK-NEXT: ret i32 390} 391 392; Callee with null_pointer_is_valid attribute should not be inlined 393; into a caller without this attribute. 394; Exception: alwaysinline callee can still be inlined but 395; null_pointer_is_valid should get copied to caller. 396 397define i32 @null-pointer-is-valid_callee0(i32 %i) null_pointer_is_valid { 398 ret i32 %i 399; CHECK: @null-pointer-is-valid_callee0(i32 %i) 400; CHECK-NEXT: ret i32 401} 402 403define i32 @null-pointer-is-valid_callee1(i32 %i) alwaysinline null_pointer_is_valid { 404 ret i32 %i 405; CHECK: @null-pointer-is-valid_callee1(i32 %i) 406; CHECK-NEXT: ret i32 407} 408 409define i32 @null-pointer-is-valid_callee2(i32 %i) { 410 ret i32 %i 411; CHECK: @null-pointer-is-valid_callee2(i32 %i) 412; CHECK-NEXT: ret i32 413} 414 415; No inlining since caller does not have null_pointer_is_valid attribute. 416define i32 @test_null-pointer-is-valid0(i32 %i) { 417 %1 = call i32 @null-pointer-is-valid_callee0(i32 %i) 418 ret i32 %1 419; CHECK: @test_null-pointer-is-valid0( 420; CHECK: call i32 @null-pointer-is-valid_callee0 421; CHECK-NEXT: ret i32 422} 423 424; alwaysinline should force inlining even when caller does not have 425; null_pointer_is_valid attribute. However, the attribute should be 426; copied to caller. 427define i32 @test_null-pointer-is-valid1(i32 %i) { 428 %1 = call i32 @null-pointer-is-valid_callee1(i32 %i) 429 ret i32 %1 430; CHECK: @test_null-pointer-is-valid1(i32 %i) [[NULLPOINTERISVALID:#[0-9]+]] { 431; CHECK-NEXT: ret i32 432} 433 434; Can inline since both caller and callee have null_pointer_is_valid 435; attribute. 436define i32 @test_null-pointer-is-valid2(i32 %i) null_pointer_is_valid { 437 %1 = call i32 @null-pointer-is-valid_callee2(i32 %i) 438 ret i32 %1 439; CHECK: @test_null-pointer-is-valid2(i32 %i) [[NULLPOINTERISVALID]] { 440; CHECK-NEXT: ret i32 441} 442 443define i32 @no-infs-fp-math_callee0(i32 %i) "no-infs-fp-math"="false" { 444 ret i32 %i 445; CHECK: @no-infs-fp-math_callee0(i32 %i) [[NO_INFS_FPMATH_FALSE:#[0-9]+]] { 446; CHECK-NEXT: ret i32 447} 448 449define i32 @no-infs-fp-math_callee1(i32 %i) "no-infs-fp-math"="true" { 450 ret i32 %i 451; CHECK: @no-infs-fp-math_callee1(i32 %i) [[NO_INFS_FPMATH_TRUE:#[0-9]+]] { 452; CHECK-NEXT: ret i32 453} 454 455define i32 @test_no-infs-fp-math0(i32 %i) "no-infs-fp-math"="false" { 456 %1 = call i32 @no-infs-fp-math_callee0(i32 %i) 457 ret i32 %1 458; CHECK: @test_no-infs-fp-math0(i32 %i) [[NO_INFS_FPMATH_FALSE]] { 459; CHECK-NEXT: ret i32 460} 461 462define i32 @test_no-infs-fp-math1(i32 %i) "no-infs-fp-math"="false" { 463 %1 = call i32 @no-infs-fp-math_callee1(i32 %i) 464 ret i32 %1 465; CHECK: @test_no-infs-fp-math1(i32 %i) [[NO_INFS_FPMATH_FALSE]] { 466; CHECK-NEXT: ret i32 467} 468 469define i32 @test_no-infs-fp-math2(i32 %i) "no-infs-fp-math"="true" { 470 %1 = call i32 @no-infs-fp-math_callee0(i32 %i) 471 ret i32 %1 472; CHECK: @test_no-infs-fp-math2(i32 %i) [[NO_INFS_FPMATH_FALSE]] { 473; CHECK-NEXT: ret i32 474} 475 476define i32 @test_no-infs-fp-math3(i32 %i) "no-infs-fp-math"="true" { 477 %1 = call i32 @no-infs-fp-math_callee1(i32 %i) 478 ret i32 %1 479; CHECK: @test_no-infs-fp-math3(i32 %i) [[NO_INFS_FPMATH_TRUE]] { 480; CHECK-NEXT: ret i32 481} 482 483define i32 @no-nans-fp-math_callee0(i32 %i) "no-nans-fp-math"="false" { 484 ret i32 %i 485; CHECK: @no-nans-fp-math_callee0(i32 %i) [[NO_NANS_FPMATH_FALSE:#[0-9]+]] { 486; CHECK-NEXT: ret i32 487} 488 489define i32 @no-nans-fp-math_callee1(i32 %i) "no-nans-fp-math"="true" { 490 ret i32 %i 491; CHECK: @no-nans-fp-math_callee1(i32 %i) [[NO_NANS_FPMATH_TRUE:#[0-9]+]] { 492; CHECK-NEXT: ret i32 493} 494 495define i32 @test_no-nans-fp-math0(i32 %i) "no-nans-fp-math"="false" { 496 %1 = call i32 @no-nans-fp-math_callee0(i32 %i) 497 ret i32 %1 498; CHECK: @test_no-nans-fp-math0(i32 %i) [[NO_NANS_FPMATH_FALSE]] { 499; CHECK-NEXT: ret i32 500} 501 502define i32 @test_no-nans-fp-math1(i32 %i) "no-nans-fp-math"="false" { 503 %1 = call i32 @no-nans-fp-math_callee1(i32 %i) 504 ret i32 %1 505; CHECK: @test_no-nans-fp-math1(i32 %i) [[NO_NANS_FPMATH_FALSE]] { 506; CHECK-NEXT: ret i32 507} 508 509define i32 @test_no-nans-fp-math2(i32 %i) "no-nans-fp-math"="true" { 510 %1 = call i32 @no-nans-fp-math_callee0(i32 %i) 511 ret i32 %1 512; CHECK: @test_no-nans-fp-math2(i32 %i) [[NO_NANS_FPMATH_FALSE]] { 513; CHECK-NEXT: ret i32 514} 515 516define i32 @test_no-nans-fp-math3(i32 %i) "no-nans-fp-math"="true" { 517 %1 = call i32 @no-nans-fp-math_callee1(i32 %i) 518 ret i32 %1 519; CHECK: @test_no-nans-fp-math3(i32 %i) [[NO_NANS_FPMATH_TRUE]] { 520; CHECK-NEXT: ret i32 521} 522 523define i32 @no-signed-zeros-fp-math_callee0(i32 %i) "no-signed-zeros-fp-math"="false" { 524 ret i32 %i 525; CHECK: @no-signed-zeros-fp-math_callee0(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_FALSE:#[0-9]+]] { 526; CHECK-NEXT: ret i32 527} 528 529define i32 @no-signed-zeros-fp-math_callee1(i32 %i) "no-signed-zeros-fp-math"="true" { 530 ret i32 %i 531; CHECK: @no-signed-zeros-fp-math_callee1(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_TRUE:#[0-9]+]] { 532; CHECK-NEXT: ret i32 533} 534 535define i32 @test_no-signed-zeros-fp-math0(i32 %i) "no-signed-zeros-fp-math"="false" { 536 %1 = call i32 @no-signed-zeros-fp-math_callee0(i32 %i) 537 ret i32 %1 538; CHECK: @test_no-signed-zeros-fp-math0(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_FALSE]] { 539; CHECK-NEXT: ret i32 540} 541 542define i32 @test_no-signed-zeros-fp-math1(i32 %i) "no-signed-zeros-fp-math"="false" { 543 %1 = call i32 @no-signed-zeros-fp-math_callee1(i32 %i) 544 ret i32 %1 545; CHECK: @test_no-signed-zeros-fp-math1(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_FALSE]] { 546; CHECK-NEXT: ret i32 547} 548 549define i32 @test_no-signed-zeros-fp-math2(i32 %i) "no-signed-zeros-fp-math"="true" { 550 %1 = call i32 @no-signed-zeros-fp-math_callee0(i32 %i) 551 ret i32 %1 552; CHECK: @test_no-signed-zeros-fp-math2(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_FALSE]] { 553; CHECK-NEXT: ret i32 554} 555 556define i32 @test_no-signed-zeros-fp-math3(i32 %i) "no-signed-zeros-fp-math"="true" { 557 %1 = call i32 @no-signed-zeros-fp-math_callee1(i32 %i) 558 ret i32 %1 559; CHECK: @test_no-signed-zeros-fp-math3(i32 %i) [[NO_SIGNED_ZEROS_FPMATH_TRUE]] { 560; CHECK-NEXT: ret i32 561} 562 563define i32 @unsafe-fp-math_callee0(i32 %i) "unsafe-fp-math"="false" { 564 ret i32 %i 565; CHECK: @unsafe-fp-math_callee0(i32 %i) [[UNSAFE_FPMATH_FALSE:#[0-9]+]] { 566; CHECK-NEXT: ret i32 567} 568 569define i32 @unsafe-fp-math_callee1(i32 %i) "unsafe-fp-math"="true" { 570 ret i32 %i 571; CHECK: @unsafe-fp-math_callee1(i32 %i) [[UNSAFE_FPMATH_TRUE:#[0-9]+]] { 572; CHECK-NEXT: ret i32 573} 574 575define i32 @test_unsafe-fp-math0(i32 %i) "unsafe-fp-math"="false" { 576 %1 = call i32 @unsafe-fp-math_callee0(i32 %i) 577 ret i32 %1 578; CHECK: @test_unsafe-fp-math0(i32 %i) [[UNSAFE_FPMATH_FALSE]] { 579; CHECK-NEXT: ret i32 580} 581 582define i32 @test_unsafe-fp-math1(i32 %i) "unsafe-fp-math"="false" { 583 %1 = call i32 @unsafe-fp-math_callee1(i32 %i) 584 ret i32 %1 585; CHECK: @test_unsafe-fp-math1(i32 %i) [[UNSAFE_FPMATH_FALSE]] { 586; CHECK-NEXT: ret i32 587} 588 589define i32 @test_unsafe-fp-math2(i32 %i) "unsafe-fp-math"="true" { 590 %1 = call i32 @unsafe-fp-math_callee0(i32 %i) 591 ret i32 %1 592; CHECK: @test_unsafe-fp-math2(i32 %i) [[UNSAFE_FPMATH_FALSE]] { 593; CHECK-NEXT: ret i32 594} 595 596define i32 @test_unsafe-fp-math3(i32 %i) "unsafe-fp-math"="true" { 597 %1 = call i32 @unsafe-fp-math_callee1(i32 %i) 598 ret i32 %1 599; CHECK: @test_unsafe-fp-math3(i32 %i) [[UNSAFE_FPMATH_TRUE]] { 600; CHECK-NEXT: ret i32 601} 602 603; Test that fn_ret_thunk_extern has no CompatRule; inlining is permitted. 604; Test that fn_ret_thunk_extern has no MergeRule; fn_ret_thunk_extern is not 605; propagated or dropped on the caller after inlining. 606define i32 @thunk_extern_callee() fn_ret_thunk_extern { 607; CHECK: @thunk_extern_callee() [[FNRETTHUNK_EXTERN:#[0-9]+]] 608 ret i32 42 609} 610 611define i32 @thunk_keep_caller() { 612; CHECK: @thunk_keep_caller() { 613; CHECK-NEXT: ret i32 42 614 %1 = call i32 @thunk_extern_callee() 615 ret i32 %1 616} 617 618define i32 @thunk_keep_callee() { 619; CHECK: @thunk_keep_callee() { 620 ret i32 42 621} 622 623define i32 @thunk_extern_caller() fn_ret_thunk_extern { 624; CHECK: @thunk_extern_caller() [[FNRETTHUNK_EXTERN]] 625; CHECK-NEXT: ret i32 42 626 %1 = call i32 @thunk_keep_callee() 627 ret i32 %1 628} 629 630; CHECK: attributes [[SLH]] = { speculative_load_hardening } 631; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" } 632; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" } 633; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat } 634; CHECK: attributes [[NOUSEJUMPTABLES]] = { "no-jump-tables"="true" } 635; CHECK: attributes [[NULLPOINTERISVALID]] = { null_pointer_is_valid } 636; CHECK: attributes [[NO_INFS_FPMATH_FALSE]] = { "no-infs-fp-math"="false" } 637; CHECK: attributes [[NO_INFS_FPMATH_TRUE]] = { "no-infs-fp-math"="true" } 638; CHECK: attributes [[NO_NANS_FPMATH_FALSE]] = { "no-nans-fp-math"="false" } 639; CHECK: attributes [[NO_NANS_FPMATH_TRUE]] = { "no-nans-fp-math"="true" } 640; CHECK: attributes [[NO_SIGNED_ZEROS_FPMATH_FALSE]] = { "no-signed-zeros-fp-math"="false" } 641; CHECK: attributes [[NO_SIGNED_ZEROS_FPMATH_TRUE]] = { "no-signed-zeros-fp-math"="true" } 642; CHECK: attributes [[UNSAFE_FPMATH_FALSE]] = { "unsafe-fp-math"="false" } 643; CHECK: attributes [[UNSAFE_FPMATH_TRUE]] = { "unsafe-fp-math"="true" } 644; CHECK: attributes [[FNRETTHUNK_EXTERN]] = { fn_ret_thunk_extern } 645