677 lines
21 KiB
LLVM
677 lines
21 KiB
LLVM
; 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
|
|
}
|