; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+sme -S -passes=inline | FileCheck %s declare i32 @llvm.vscale.i32() ; Define some functions that merely call llvm.vscale.i32(), which will be called ; by the other functions below. If we see the call to one of these functions ; being replaced by 'llvm.vscale()', then we know it has been inlined. define i32 @normal_callee() { ; CHECK-LABEL: define i32 @normal_callee ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @llvm.vscale.i32() ret i32 %res } define i32 @streaming_callee() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_callee ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @llvm.vscale.i32() ret i32 %res } define i32 @locally_streaming_callee() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_callee ; CHECK-SAME: () #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @llvm.vscale.i32() ret i32 %res } define i32 @streaming_compatible_callee() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_callee ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @llvm.vscale.i32() ret i32 %res } define i32 @streaming_compatible_locally_streaming_callee() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_callee ; CHECK-SAME: () #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @llvm.vscale() ret i32 %res } ; Now test that inlining only happens when their streaming modes match. ; Test for a number of combinations, where: ; N Normal-interface (PSTATE.SM=0 on entry/exit) ; S Streaming-interface (PSTATE.SM=1 on entry/exit) ; SC Streaming-compatible interface ; (PSTATE.SM=0 or 1, unchanged on exit) ; N + B Normal-interface, streaming body ; (PSTATE.SM=0 on entry/exit, but 1 within the body of the function) ; SC + B Streaming-compatible-interface, streaming body ; (PSTATE.SM=0 or 1 on entry, unchanged on exit, ; but guaranteed to be 1 within the body of the function) ; [x] N -> N ; [ ] N -> S ; [ ] N -> SC ; [ ] N -> N + B ; [ ] N -> SC + B define i32 @normal_caller_normal_callee_inline() { ; CHECK-LABEL: define i32 @normal_caller_normal_callee_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @normal_callee() ret i32 %res } ; [ ] N -> N ; [x] N -> S ; [ ] N -> SC ; [ ] N -> N + B ; [ ] N -> SC + B define i32 @normal_caller_streaming_callee_dont_inline() { ; CHECK-LABEL: define i32 @normal_caller_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @streaming_callee() ret i32 %res } ; [ ] N -> N ; [ ] N -> S ; [x] N -> SC ; [ ] N -> N + B ; [ ] N -> SC + B define i32 @normal_caller_streaming_compatible_callee_inline() { ; CHECK-LABEL: define i32 @normal_caller_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_callee() ret i32 %res } ; [ ] N -> N ; [ ] N -> S ; [ ] N -> SC ; [x] N -> N + B ; [ ] N -> SC + B define i32 @normal_caller_locally_streaming_callee_dont_inline() { ; CHECK-LABEL: define i32 @normal_caller_locally_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @locally_streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @locally_streaming_callee() ret i32 %res } ; [ ] N -> N ; [ ] N -> S ; [ ] N -> SC ; [ ] N -> N + B ; [x] N -> SC + B define i32 @normal_caller_streaming_compatible_locally_streaming_callee_dont_inline() { ; CHECK-LABEL: define i32 @normal_caller_streaming_compatible_locally_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @streaming_compatible_locally_streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @streaming_compatible_locally_streaming_callee() ret i32 %res } ; [x] S -> N ; [ ] S -> S ; [ ] S -> SC ; [ ] S -> N + B ; [ ] S -> SC + B define i32 @streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_caller_normal_callee_dont_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @normal_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @normal_callee() ret i32 %res } ; [ ] S -> N ; [x] S -> S ; [ ] S -> SC ; [ ] S -> N + B ; [ ] S -> SC + B define i32 @streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_caller_streaming_callee_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_callee() ret i32 %res } ; [ ] S -> N ; [ ] S -> S ; [x] S -> SC ; [ ] S -> N + B ; [ ] S -> SC + B define i32 @streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_caller_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_callee() ret i32 %res } ; [ ] S -> N ; [ ] S -> S ; [ ] S -> SC ; [x] S -> N + B ; [ ] S -> SC + B define i32 @streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_caller_locally_streaming_callee_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @locally_streaming_callee() ret i32 %res } ; [ ] S -> N ; [ ] S -> S ; [ ] S -> SC ; [ ] S -> N + B ; [x] S -> SC + B define i32 @streaming_caller_streaming_compatible_locally_streaming_callee_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i32 @streaming_caller_streaming_compatible_locally_streaming_callee_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_locally_streaming_callee() ret i32 %res } ; [x] N + B -> N ; [ ] N + B -> S ; [ ] N + B -> SC ; [ ] N + B -> N + B ; [ ] N + B -> SC + B define i32 @locally_streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_caller_normal_callee_dont_inline ; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @normal_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @normal_callee() ret i32 %res } ; [ ] N + B -> N ; [x] N + B -> S ; [ ] N + B -> SC ; [ ] N + B -> N + B ; [ ] N + B -> SC + B define i32 @locally_streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_callee_inline ; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_callee() ret i32 %res } ; [ ] N + B -> N ; [ ] N + B -> S ; [x] N + B -> SC ; [ ] N + B -> N + B ; [ ] N + B -> SC + B define i32 @locally_streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_callee() ret i32 %res } ; [ ] N + B -> N ; [ ] N + B -> S ; [ ] N + B -> SC ; [x] N + B -> N + B ; [ ] N + B -> SC + B define i32 @locally_streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_caller_locally_streaming_callee_inline ; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @locally_streaming_callee() ret i32 %res } ; [ ] N + B -> N ; [ ] N + B -> S ; [ ] N + B -> SC ; [ ] N + B -> N + B ; [x] N + B -> SC + B define i32 @locally_streaming_caller_streaming_compatible_locally_streaming_callee_inline() "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_compatible_locally_streaming_callee_inline ; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_locally_streaming_callee() ret i32 %res } ; [x] SC -> N ; [ ] SC -> S ; [ ] SC -> SC ; [ ] SC -> N + B ; [ ] SC -> SC + B define i32 @streaming_compatible_caller_normal_callee_dont_inline() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_caller_normal_callee_dont_inline ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @normal_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @normal_callee() ret i32 %res } ; [ ] SC -> N ; [x] SC -> S ; [ ] SC -> SC ; [ ] SC -> N + B ; [ ] SC -> SC + B define i32 @streaming_compatible_caller_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @streaming_callee() ret i32 %res } ; [ ] SC -> N ; [ ] SC -> S ; [x] SC -> SC ; [ ] SC -> N + B ; [ ] SC -> SC + B define i32 @streaming_compatible_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_callee() ret i32 %res } ; [ ] SC -> N ; [ ] SC -> S ; [ ] SC -> SC ; [x] SC -> N + B ; [ ] SC -> SC + B define i32 @streaming_compatible_caller_locally_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_caller_locally_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @locally_streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @locally_streaming_callee() ret i32 %res } ; [ ] SC -> N ; [ ] SC -> S ; [ ] SC -> SC ; [ ] SC -> N + B ; [x] SC -> SC + B define i32 @streaming_compatible_caller_streaming_compatible_locally_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" { ; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_compatible_locally_streaming_callee_dont_inline ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @streaming_compatible_locally_streaming_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @streaming_compatible_locally_streaming_callee() ret i32 %res } ; [x] SC + B -> N ; [ ] SC + B -> S ; [ ] SC + B -> SC ; [ ] SC + B -> N + B ; [ ] SC + B -> SC + B define i32 @streaming_compatible_locally_streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_normal_callee_dont_inline ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i32 @normal_callee() ; CHECK-NEXT: ret i32 [[RES]] ; entry: %res = call i32 @normal_callee() ret i32 %res } ; [ ] SC + B -> N ; [x] SC + B -> S ; [ ] SC + B -> SC ; [ ] SC + B -> N + B ; [ ] SC + B -> SC + B define i32 @streaming_compatible_locally_streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_streaming_callee_inline ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_callee() ret i32 %res } ; [ ] SC + B -> N ; [ ] SC + B -> S ; [x] SC + B -> SC ; [ ] SC + B -> N + B ; [ ] SC + B -> SC + B define i32 @streaming_compatible_locally_streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_callee() ret i32 %res } ; [ ] SC + B -> N ; [ ] SC + B -> S ; [ ] SC + B -> SC ; [x] SC + B -> N + B ; [ ] SC + B -> SC + B define i32 @streaming_compatible_locally_streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_locally_streaming_callee_inline ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @locally_streaming_callee() ret i32 %res } ; [ ] SC + B -> N ; [ ] SC + B -> S ; [ ] SC + B -> SC ; [ ] SC + B -> N + B ; [x] SC + B -> SC + B define i32 @streaming_compatible_locally_streaming_caller_and_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" { ; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_and_callee_inline ; CHECK-SAME: () #[[ATTR4]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES_I:%.*]] = call i32 @llvm.vscale.i32() ; CHECK-NEXT: ret i32 [[RES_I]] ; entry: %res = call i32 @streaming_compatible_locally_streaming_callee() ret i32 %res } define void @normal_callee_with_inlineasm() { ; CHECK-LABEL: define void @normal_callee_with_inlineasm ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: call void asm sideeffect " ; CHECK-NEXT: ret void ; entry: call void asm sideeffect "; inlineasm", ""() ret void } define void @streaming_caller_normal_callee_with_inlineasm_dont_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define void @streaming_caller_normal_callee_with_inlineasm_dont_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @normal_callee_with_inlineasm() ; CHECK-NEXT: ret void ; entry: call void @normal_callee_with_inlineasm() ret void } define i64 @normal_callee_with_intrinsic_call() { ; CHECK-LABEL: define i64 @normal_callee_with_intrinsic_call ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.aarch64.sve.cntb(i32 4) ; CHECK-NEXT: ret i64 [[RES]] ; entry: %res = call i64 @llvm.aarch64.sve.cntb(i32 4) ret i64 %res } define i64 @streaming_caller_normal_callee_with_intrinsic_call_dont_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i64 @streaming_caller_normal_callee_with_intrinsic_call_dont_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i64 @normal_callee_with_intrinsic_call() ; CHECK-NEXT: ret i64 [[RES]] ; entry: %res = call i64 @normal_callee_with_intrinsic_call() ret i64 %res } declare i64 @llvm.aarch64.sve.cntb(i32) define i64 @normal_callee_call_sme_state() { ; CHECK-LABEL: define i64 @normal_callee_call_sme_state ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call { i64, i64 } @__arm_sme_state() ; CHECK-NEXT: [[RES_0:%.*]] = extractvalue { i64, i64 } [[RES]], 0 ; CHECK-NEXT: ret i64 [[RES_0]] ; entry: %res = call {i64, i64} @__arm_sme_state() %res.0 = extractvalue {i64, i64} %res, 0 ret i64 %res.0 } declare {i64, i64} @__arm_sme_state() define i64 @streaming_caller_normal_callee_call_sme_state_dont_inline() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define i64 @streaming_caller_normal_callee_call_sme_state_dont_inline ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RES:%.*]] = call i64 @normal_callee_call_sme_state() ; CHECK-NEXT: ret i64 [[RES]] ; entry: %res = call i64 @normal_callee_call_sme_state() ret i64 %res } declare void @streaming_body() "aarch64_pstate_sm_enabled" define void @streaming_caller_single_streaming_callee() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define void @streaming_caller_single_streaming_callee ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: call void @streaming_body() ; CHECK-NEXT: ret void ; call void @streaming_body() ret void } define void @streaming_caller_multiple_streaming_callees() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define void @streaming_caller_multiple_streaming_callees ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: call void @streaming_body() ; CHECK-NEXT: call void @streaming_body() ; CHECK-NEXT: ret void ; call void @streaming_body() call void @streaming_body() ret void } ; Allow inlining, as inline it would not increase the number of streaming-mode changes. define void @streaming_caller_single_streaming_callee_inline() { ; CHECK-LABEL: define void @streaming_caller_single_streaming_callee_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: call void @streaming_body() ; CHECK-NEXT: ret void ; call void @streaming_caller_single_streaming_callee() ret void } ; Prevent inlining, as inline it would lead to multiple streaming-mode changes. define void @streaming_caller_multiple_streaming_callees_dont_inline() { ; CHECK-LABEL: define void @streaming_caller_multiple_streaming_callees_dont_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: call void @streaming_caller_multiple_streaming_callees() ; CHECK-NEXT: ret void ; call void @streaming_caller_multiple_streaming_callees() ret void } declare void @streaming_compatible_body() "aarch64_pstate_sm_compatible" define void @streaming_caller_single_streaming_compatible_callee() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define void @streaming_caller_single_streaming_compatible_callee ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: ret void ; call void @streaming_compatible_body() ret void } define void @streaming_caller_multiple_streaming_compatible_callees() "aarch64_pstate_sm_enabled" { ; CHECK-LABEL: define void @streaming_caller_multiple_streaming_compatible_callees ; CHECK-SAME: () #[[ATTR2]] { ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: ret void ; call void @streaming_compatible_body() call void @streaming_compatible_body() ret void } ; Allow inlining, as inline would remove a streaming-mode change. define void @streaming_caller_single_streaming_compatible_callee_inline() { ; CHECK-LABEL: define void @streaming_caller_single_streaming_compatible_callee_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: ret void ; call void @streaming_caller_single_streaming_compatible_callee() ret void } ; Allow inlining, as inline would remove several stremaing-mode changes. define void @streaming_caller_multiple_streaming_compatible_callees_inline() { ; CHECK-LABEL: define void @streaming_caller_multiple_streaming_compatible_callees_inline ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: call void @streaming_compatible_body() ; CHECK-NEXT: ret void ; call void @streaming_caller_multiple_streaming_compatible_callees() ret void }