1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -mtriple=aarch64-unknown-linux-gnu -mattr=+sme -S -passes=inline < %s | FileCheck %s 3 4declare void @inlined_body() 5 6; 7; Define some functions that will be called by the functions below. 8; These just call a '...body()' function. If we see the call to one of 9; these functions being replaced by '...body()', then we know it has been 10; inlined. 11; 12 13define void @nonza_callee() { 14; CHECK-LABEL: define void @nonza_callee 15; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 16; CHECK-NEXT: entry: 17; CHECK-NEXT: call void asm sideeffect " 18; CHECK-NEXT: call void @inlined_body() 19; CHECK-NEXT: ret void 20; 21entry: 22 call void asm sideeffect "; inlineasm", ""() 23 call void @inlined_body() 24 ret void 25} 26 27define void @shared_za_callee() "aarch64_inout_za" { 28; CHECK-LABEL: define void @shared_za_callee 29; CHECK-SAME: () #[[ATTR1:[0-9]+]] { 30; CHECK-NEXT: entry: 31; CHECK-NEXT: call void asm sideeffect " 32; CHECK-NEXT: call void @inlined_body() 33; CHECK-NEXT: ret void 34; 35entry: 36 call void asm sideeffect "; inlineasm", ""() 37 call void @inlined_body() 38 ret void 39} 40 41define void @new_za_callee() "aarch64_new_za" { 42; CHECK-LABEL: define void @new_za_callee 43; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 44; CHECK-NEXT: call void asm sideeffect " 45; CHECK-NEXT: call void @inlined_body() 46; CHECK-NEXT: ret void 47; 48 call void asm sideeffect "; inlineasm", ""() 49 call void @inlined_body() 50 ret void 51} 52 53define void @agnostic_za_callee() "aarch64_za_state_agnostic" { 54; CHECK-LABEL: define void @agnostic_za_callee 55; CHECK-SAME: () #[[ATTR3:[0-9]+]] { 56; CHECK-NEXT: call void asm sideeffect " 57; CHECK-NEXT: call void @inlined_body() 58; CHECK-NEXT: ret void 59; 60 call void asm sideeffect "; inlineasm", ""() 61 call void @inlined_body() 62 ret void 63} 64 65; 66; Now test that inlining only happens when no lazy-save is needed. 67; Test for a number of combinations, where: 68; N Not using ZA. 69; S Shared ZA interface 70; Z New ZA with Private-ZA interface 71; A Agnostic ZA interface 72 73; [x] N -> N 74; [ ] N -> S (This combination is invalid) 75; [ ] N -> Z 76; [ ] N -> A 77define void @nonza_caller_nonza_callee_inline() { 78; CHECK-LABEL: define void @nonza_caller_nonza_callee_inline 79; CHECK-SAME: () #[[ATTR0]] { 80; CHECK-NEXT: entry: 81; CHECK-NEXT: call void asm sideeffect " 82; CHECK-NEXT: call void @inlined_body() 83; CHECK-NEXT: ret void 84; 85entry: 86 call void @nonza_callee() 87 ret void 88} 89 90; [ ] N -> N 91; [ ] N -> S (This combination is invalid) 92; [x] N -> Z 93; [ ] N -> A 94define void @nonza_caller_new_za_callee_dont_inline() { 95; CHECK-LABEL: define void @nonza_caller_new_za_callee_dont_inline 96; CHECK-SAME: () #[[ATTR0]] { 97; CHECK-NEXT: entry: 98; CHECK-NEXT: call void @new_za_callee() 99; CHECK-NEXT: ret void 100; 101entry: 102 call void @new_za_callee() 103 ret void 104} 105 106; [ ] N -> N 107; [ ] N -> S (This combination is invalid) 108; [ ] N -> Z 109; [x] N -> A 110define void @nonza_caller_agnostic_za_callee_inline() { 111; CHECK-LABEL: define void @nonza_caller_agnostic_za_callee_inline 112; CHECK-SAME: () #[[ATTR0]] { 113; CHECK-NEXT: entry: 114; CHECK-NEXT: call void asm sideeffect " 115; CHECK-NEXT: call void @inlined_body() 116; CHECK-NEXT: ret void 117; 118entry: 119 call void @agnostic_za_callee() 120 ret void 121} 122 123; [x] Z -> N 124; [ ] Z -> S 125; [ ] Z -> Z 126; [ ] Z -> A 127define void @new_za_caller_nonza_callee_dont_inline() "aarch64_new_za" { 128; CHECK-LABEL: define void @new_za_caller_nonza_callee_dont_inline 129; CHECK-SAME: () #[[ATTR2]] { 130; CHECK-NEXT: entry: 131; CHECK-NEXT: call void @nonza_callee() 132; CHECK-NEXT: ret void 133; 134entry: 135 call void @nonza_callee() 136 ret void 137} 138 139; [ ] Z -> N 140; [x] Z -> S 141; [ ] Z -> Z 142; [ ] Z -> A 143define void @new_za_caller_shared_za_callee_inline() "aarch64_new_za" { 144; CHECK-LABEL: define void @new_za_caller_shared_za_callee_inline 145; CHECK-SAME: () #[[ATTR2]] { 146; CHECK-NEXT: entry: 147; CHECK-NEXT: call void asm sideeffect " 148; CHECK-NEXT: call void @inlined_body() 149; CHECK-NEXT: ret void 150; 151entry: 152 call void @shared_za_callee() 153 ret void 154} 155 156; [ ] Z -> N 157; [ ] Z -> S 158; [x] Z -> Z 159; [ ] Z -> A 160define void @new_za_caller_new_za_callee_dont_inline() "aarch64_new_za" { 161; CHECK-LABEL: define void @new_za_caller_new_za_callee_dont_inline 162; CHECK-SAME: () #[[ATTR2]] { 163; CHECK-NEXT: entry: 164; CHECK-NEXT: call void @new_za_callee() 165; CHECK-NEXT: ret void 166; 167entry: 168 call void @new_za_callee() 169 ret void 170} 171 172; [ ] Z -> N 173; [ ] Z -> S 174; [ ] Z -> Z 175; [x] Z -> A 176define void @new_za_caller_agnostic_za_callee_inline() "aarch64_new_za" { 177; CHECK-LABEL: define void @new_za_caller_agnostic_za_callee_inline 178; CHECK-SAME: () #[[ATTR2]] { 179; CHECK-NEXT: entry: 180; CHECK-NEXT: call void asm sideeffect " 181; CHECK-NEXT: call void @inlined_body() 182; CHECK-NEXT: ret void 183; 184entry: 185 call void @agnostic_za_callee() 186 ret void 187} 188 189; [x] S -> N 190; [ ] S -> S 191; [ ] S -> Z 192; [ ] S -> A 193define void @shared_za_caller_nonza_callee_dont_inline() "aarch64_inout_za" { 194; CHECK-LABEL: define void @shared_za_caller_nonza_callee_dont_inline 195; CHECK-SAME: () #[[ATTR1]] { 196; CHECK-NEXT: entry: 197; CHECK-NEXT: call void @nonza_callee() 198; CHECK-NEXT: ret void 199; 200entry: 201 call void @nonza_callee() 202 ret void 203} 204 205; [ ] S -> N 206; [x] S -> Z 207; [ ] S -> S 208; [ ] S -> A 209define void @shared_za_caller_new_za_callee_dont_inline() "aarch64_inout_za" { 210; CHECK-LABEL: define void @shared_za_caller_new_za_callee_dont_inline 211; CHECK-SAME: () #[[ATTR1]] { 212; CHECK-NEXT: entry: 213; CHECK-NEXT: call void @new_za_callee() 214; CHECK-NEXT: ret void 215; 216entry: 217 call void @new_za_callee() 218 ret void 219} 220 221; [ ] S -> N 222; [ ] S -> Z 223; [x] S -> S 224; [ ] S -> A 225define void @shared_za_caller_shared_za_callee_inline() "aarch64_inout_za" { 226; CHECK-LABEL: define void @shared_za_caller_shared_za_callee_inline 227; CHECK-SAME: () #[[ATTR1]] { 228; CHECK-NEXT: entry: 229; CHECK-NEXT: call void asm sideeffect " 230; CHECK-NEXT: call void @inlined_body() 231; CHECK-NEXT: ret void 232; 233entry: 234 call void @shared_za_callee() 235 ret void 236} 237 238; [ ] S -> N 239; [ ] S -> Z 240; [ ] S -> S 241; [x] S -> A 242define void @shared_za_caller_agnostic_za_callee_inline() "aarch64_inout_za" { 243; CHECK-LABEL: define void @shared_za_caller_agnostic_za_callee_inline 244; CHECK-SAME: () #[[ATTR1]] { 245; CHECK-NEXT: entry: 246; CHECK-NEXT: call void asm sideeffect " 247; CHECK-NEXT: call void @inlined_body() 248; CHECK-NEXT: ret void 249; 250entry: 251 call void @agnostic_za_callee() 252 ret void 253} 254 255; [x] A -> N 256; [ ] A -> Z 257; [ ] A -> S 258; [ ] A -> A 259define void @agnostic_za_caller_nonza_callee_dont_inline() "aarch64_za_state_agnostic" { 260; CHECK-LABEL: define void @agnostic_za_caller_nonza_callee_dont_inline 261; CHECK-SAME: () #[[ATTR3]] { 262; CHECK-NEXT: entry: 263; CHECK-NEXT: call void @nonza_callee() 264; CHECK-NEXT: ret void 265; 266entry: 267 call void @nonza_callee() 268 ret void 269} 270 271; [ ] A -> N 272; [x] A -> Z 273; [ ] A -> S 274; [ ] A -> A 275define void @agnostic_za_caller_new_za_callee_dont_inline() "aarch64_za_state_agnostic" { 276; CHECK-LABEL: define void @agnostic_za_caller_new_za_callee_dont_inline 277; CHECK-SAME: () #[[ATTR3]] { 278; CHECK-NEXT: entry: 279; CHECK-NEXT: call void @new_za_callee() 280; CHECK-NEXT: ret void 281; 282entry: 283 call void @new_za_callee() 284 ret void 285} 286 287; [ ] A -> N 288; [ ] A -> Z 289; [x] A -> S (invalid) 290; [ ] A -> A 291define void @agnostic_za_caller_shared_za_callee_dont_inline() "aarch64_za_state_agnostic" { 292; CHECK-LABEL: define void @agnostic_za_caller_shared_za_callee_dont_inline 293; CHECK-SAME: () #[[ATTR3]] { 294; CHECK-NEXT: entry: 295; CHECK-NEXT: call void @shared_za_callee() 296; CHECK-NEXT: ret void 297; 298entry: 299 call void @shared_za_callee() 300 ret void 301} 302 303; [ ] A -> N 304; [ ] A -> Z 305; [ ] A -> S 306; [x] A -> A 307define void @agnostic_za_caller_agnostic_za_callee_inline() "aarch64_za_state_agnostic" { 308; CHECK-LABEL: define void @agnostic_za_caller_agnostic_za_callee_inline 309; CHECK-SAME: () #[[ATTR3]] { 310; CHECK-NEXT: entry: 311; CHECK-NEXT: call void asm sideeffect " 312; CHECK-NEXT: call void @inlined_body() 313; CHECK-NEXT: ret void 314; 315entry: 316 call void @agnostic_za_callee() 317 ret void 318} 319 320 321 322define void @private_za_callee_call_za_disable() { 323; CHECK-LABEL: define void @private_za_callee_call_za_disable 324; CHECK-SAME: () #[[ATTR0]] { 325; CHECK-NEXT: call void @__arm_za_disable() 326; CHECK-NEXT: ret void 327; 328 call void @__arm_za_disable() 329 ret void 330} 331 332define void @shared_za_caller_private_za_callee_call_za_disable() "aarch64_inout_za" { 333; CHECK-LABEL: define void @shared_za_caller_private_za_callee_call_za_disable 334; CHECK-SAME: () #[[ATTR1]] { 335; CHECK-NEXT: call void @private_za_callee_call_za_disable() 336; CHECK-NEXT: ret void 337; 338 call void @private_za_callee_call_za_disable() 339 ret void 340} 341 342define void @private_za_callee_call_tpidr2_save() { 343; CHECK-LABEL: define void @private_za_callee_call_tpidr2_save 344; CHECK-SAME: () #[[ATTR0]] { 345; CHECK-NEXT: call void @__arm_tpidr2_save() 346; CHECK-NEXT: ret void 347; 348 call void @__arm_tpidr2_save() 349 ret void 350} 351 352define void @shared_za_caller_private_za_callee_call_tpidr2_save_dont_inline() "aarch64_inout_za" { 353; CHECK-LABEL: define void @shared_za_caller_private_za_callee_call_tpidr2_save_dont_inline 354; CHECK-SAME: () #[[ATTR1]] { 355; CHECK-NEXT: call void @private_za_callee_call_tpidr2_save() 356; CHECK-NEXT: ret void 357; 358 call void @private_za_callee_call_tpidr2_save() 359 ret void 360} 361 362define void @private_za_callee_call_tpidr2_restore(ptr %ptr) { 363; CHECK-LABEL: define void @private_za_callee_call_tpidr2_restore 364; CHECK-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] { 365; CHECK-NEXT: call void @__arm_tpidr2_restore(ptr [[PTR]]) 366; CHECK-NEXT: ret void 367; 368 call void @__arm_tpidr2_restore(ptr %ptr) 369 ret void 370} 371 372define void @shared_za_caller_private_za_callee_call_tpidr2_restore_dont_inline(ptr %ptr) "aarch64_inout_za" { 373; CHECK-LABEL: define void @shared_za_caller_private_za_callee_call_tpidr2_restore_dont_inline 374; CHECK-SAME: (ptr [[PTR:%.*]]) #[[ATTR1]] { 375; CHECK-NEXT: call void @private_za_callee_call_tpidr2_restore(ptr [[PTR]]) 376; CHECK-NEXT: ret void 377; 378 call void @private_za_callee_call_tpidr2_restore(ptr %ptr) 379 ret void 380} 381 382define void @nonzt0_callee() { 383; CHECK-LABEL: define void @nonzt0_callee 384; CHECK-SAME: () #[[ATTR0]] { 385; CHECK-NEXT: call void asm sideeffect " 386; CHECK-NEXT: call void @inlined_body() 387; CHECK-NEXT: ret void 388; 389 call void asm sideeffect "; inlineasm", ""() 390 call void @inlined_body() 391 ret void 392} 393 394define void @new_zt0_callee() "aarch64_new_zt0" { 395; CHECK-LABEL: define void @new_zt0_callee 396; CHECK-SAME: () #[[ATTR4:[0-9]+]] { 397; CHECK-NEXT: call void asm sideeffect " 398; CHECK-NEXT: call void @inlined_body() 399; CHECK-NEXT: ret void 400; 401 call void asm sideeffect "; inlineasm", ""() 402 call void @inlined_body() 403 ret void 404} 405 406define void @nonzt0_caller_new_zt0_callee_dont_inline() { 407; CHECK-LABEL: define void @nonzt0_caller_new_zt0_callee_dont_inline 408; CHECK-SAME: () #[[ATTR0]] { 409; CHECK-NEXT: entry: 410; CHECK-NEXT: call void @new_zt0_callee() 411; CHECK-NEXT: ret void 412; 413entry: 414 call void @new_zt0_callee() 415 ret void 416} 417 418define void @shared_zt0_caller_nonzt0_callee_dont_inline() "aarch64_inout_zt0" { 419; CHECK-LABEL: define void @shared_zt0_caller_nonzt0_callee_dont_inline 420; CHECK-SAME: () #[[ATTR5:[0-9]+]] { 421; CHECK-NEXT: call void @nonzt0_callee() 422; CHECK-NEXT: ret void 423; 424 call void @nonzt0_callee() 425 ret void 426} 427 428define void @shared_zt0_callee() "aarch64_inout_zt0" { 429; CHECK-LABEL: define void @shared_zt0_callee 430; CHECK-SAME: () #[[ATTR5]] { 431; CHECK-NEXT: call void asm sideeffect " 432; CHECK-NEXT: call void @inlined_body() 433; CHECK-NEXT: ret void 434; 435 call void asm sideeffect "; inlineasm", ""() 436 call void @inlined_body() 437 ret void 438} 439 440define void @shared_zt0_caller_shared_zt0_callee_inline() "aarch64_inout_zt0" { 441; CHECK-LABEL: define void @shared_zt0_caller_shared_zt0_callee_inline 442; CHECK-SAME: () #[[ATTR5]] { 443; CHECK-NEXT: call void asm sideeffect " 444; CHECK-NEXT: call void @inlined_body() 445; CHECK-NEXT: ret void 446; 447 call void @shared_zt0_callee() 448 ret void 449} 450 451declare void @__arm_za_disable() 452declare void @__arm_tpidr2_save() 453declare void @__arm_tpidr2_restore(ptr) 454