199 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 52; RUN: llc -mtriple=aarch64 -aarch64-streaming-hazard-size=0 -mattr=+sme,+sve -stop-before=finalize-isel -verify-machineinstrs < %s | FileCheck %s3 4target triple = "aarch64-unknown-linux-gnu"5 6declare void @"StreamingCleanup::~StreamingCleanup"(ptr %this) nounwind "aarch64_pstate_sm_enabled"7declare void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %this) nounwind "aarch64_pstate_sm_compatible"8 9declare void @may_throw() "aarch64_pstate_sm_compatible"10 11; This test models the kind of IR clang would emit for the following C++:12;13; struct StreamingCleanup {14; ~StreamingCleanup() __arm_streaming15; };16;17; void may_throw() __arm_streaming_compatible;18;19; void streaming_with_cleanup() __arm_streaming {20; StreamingCleanup cleanup;21; may_throw();22; }23;24; This is a streaming function and all callees of this function are streaming[-compatible]25; functions (including the StreamingCleanup destructor). This means call lowering will not26; insert any streaming mode switches. However, if "may_throw" throws an exception, the27; unwinder can re-enter this function (in %unwind_cleanup) to run the "StreamingCleanup"28; destructor. The unwinder will always re-enter functions with streaming-mode disabled, so29; we must ensure streaming-mode is enabled on entry to exception handlers.30define void @streaming_with_cleanup() "aarch64_pstate_sm_enabled" personality ptr @__gxx_personality_v0 {31 ; CHECK-LABEL: name: streaming_with_cleanup32 ; CHECK: bb.0 (%ir-block.0):33 ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)34 ; CHECK-NEXT: {{ $}}35 ; CHECK-NEXT: EH_LABEL <mcsymbol >36 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp37 ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp38 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp39 ; CHECK-NEXT: EH_LABEL <mcsymbol >40 ; CHECK-NEXT: B %bb.141 ; CHECK-NEXT: {{ $}}42 ; CHECK-NEXT: bb.1.normal_return:43 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp44 ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 045 ; CHECK-NEXT: $x0 = COPY [[ADDXri]]46 ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp47 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp48 ; CHECK-NEXT: RET_ReallyLR49 ; CHECK-NEXT: {{ $}}50 ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):51 ; CHECK-NEXT: liveins: $x0, $x152 ; CHECK-NEXT: {{ $}}53 ; CHECK-NEXT: EH_LABEL <mcsymbol >54 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x155 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x056 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr57 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp58 ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 059 ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]60 ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp61 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp62 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp63 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr64 ; CHECK-NEXT: $x0 = COPY [[COPY1]]65 ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp66 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp67 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr68 %cleanup = alloca i8, align 169 invoke void @may_throw()70 to label %normal_return unwind label %unwind_cleanup71 72normal_return:73 call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)74 ret void75 76unwind_cleanup:77 %eh_info = landingpad { ptr, i32 }78 cleanup79 call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)80 resume { ptr, i32 } %eh_info81}82 83; This test is the same as "streaming_with_cleanup", but now the function and destructor84; are streaming-compatible functions. In this case, when we enter the exception handler,85; we must switch to streaming-mode "streaming_compatible_with_cleanup" was entered with86; during normal execution (i.e., EntryPStateSM).87define void @streaming_compatible_with_cleanup() "aarch64_pstate_sm_compatible" personality ptr @__gxx_personality_v0 {88 ; CHECK-LABEL: name: streaming_compatible_with_cleanup89 ; CHECK: bb.0 (%ir-block.0):90 ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)91 ; CHECK-NEXT: {{ $}}92 ; CHECK-NEXT: [[EntryPStateSM:%[0-9]+]]:gpr64 = EntryPStateSM93 ; CHECK-NEXT: EH_LABEL <mcsymbol >94 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp95 ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp96 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp97 ; CHECK-NEXT: EH_LABEL <mcsymbol >98 ; CHECK-NEXT: B %bb.199 ; CHECK-NEXT: {{ $}}100 ; CHECK-NEXT: bb.1.normal_return:101 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp102 ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0103 ; CHECK-NEXT: $x0 = COPY [[ADDXri]]104 ; CHECK-NEXT: BL @"StreamingCompatCleanup::~StreamingCompatCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp105 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp106 ; CHECK-NEXT: RET_ReallyLR107 ; CHECK-NEXT: {{ $}}108 ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):109 ; CHECK-NEXT: liveins: $x0, $x1110 ; CHECK-NEXT: {{ $}}111 ; CHECK-NEXT: EH_LABEL <mcsymbol >112 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x1113 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x0114 ; CHECK-NEXT: MSRpstatePseudo 1, 1, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def dead $vg, implicit $vg, implicit $vg, implicit-def $vg, implicit-def $fpmr115 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp116 ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0117 ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]118 ; CHECK-NEXT: BL @"StreamingCompatCleanup::~StreamingCompatCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp119 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp120 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp121 ; CHECK-NEXT: MSRpstatePseudo 1, 0, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def $vg, implicit $vg, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr122 ; CHECK-NEXT: $x0 = COPY [[COPY1]]123 ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $vg124 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp125 ; CHECK-NEXT: MSRpstatePseudo 1, 1, 1, [[EntryPStateSM]], csr_aarch64_smstartstop, implicit-def dead $vg, implicit $vg, implicit $vg, implicit-def $vg, implicit-def $fpmr126 %cleanup = alloca i8, align 1127 invoke void @may_throw()128 to label %normal_return unwind label %unwind_cleanup129 130normal_return:131 call void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %cleanup)132 ret void133 134unwind_cleanup:135 %eh_info = landingpad { ptr, i32 }136 cleanup137 call void @"StreamingCompatCleanup::~StreamingCompatCleanup"(ptr %cleanup)138 resume { ptr, i32 } %eh_info139}140 141; This is the same as "streaming_with_cleanup" but for a locally streaming function.142; The lowering of "unwind_cleanup" is expected to match "streaming_with_cleanup".143define void @locally_streaming_with_cleanup() "aarch64_pstate_sm_body" personality ptr @__gxx_personality_v0 {144 ; CHECK-LABEL: name: locally_streaming_with_cleanup145 ; CHECK: bb.0 (%ir-block.0):146 ; CHECK-NEXT: successors: %bb.1(0x7ffff800), %bb.2(0x00000800)147 ; CHECK-NEXT: {{ $}}148 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr149 ; CHECK-NEXT: EH_LABEL <mcsymbol >150 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp151 ; CHECK-NEXT: BL @may_throw, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp152 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp153 ; CHECK-NEXT: EH_LABEL <mcsymbol >154 ; CHECK-NEXT: B %bb.1155 ; CHECK-NEXT: {{ $}}156 ; CHECK-NEXT: bb.1.normal_return:157 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp158 ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0159 ; CHECK-NEXT: $x0 = COPY [[ADDXri]]160 ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp161 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp162 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr163 ; CHECK-NEXT: RET_ReallyLR164 ; CHECK-NEXT: {{ $}}165 ; CHECK-NEXT: bb.2.unwind_cleanup (landing-pad):166 ; CHECK-NEXT: liveins: $x0, $x1167 ; CHECK-NEXT: {{ $}}168 ; CHECK-NEXT: EH_LABEL <mcsymbol >169 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY killed $x1170 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY killed $x0171 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr172 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp173 ; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64sp = ADDXri %stack.0.cleanup, 0, 0174 ; CHECK-NEXT: $x0 = COPY [[ADDXri1]]175 ; CHECK-NEXT: BL @"StreamingCleanup::~StreamingCleanup", csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp176 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp177 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp178 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 0, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit-def $sp, implicit $vg, implicit-def $vg, implicit-def $fpmr179 ; CHECK-NEXT: $x0 = COPY [[COPY1]]180 ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp181 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp182 ; CHECK-NEXT: MSRpstatesvcrImm1 1, 1, csr_aarch64_smstartstop, implicit-def dead $nzcv, implicit $vg, implicit-def $vg, implicit-def $fpmr183 %cleanup = alloca i8, align 1184 invoke void @may_throw()185 to label %normal_return unwind label %unwind_cleanup186 187normal_return:188 call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)189 ret void190 191unwind_cleanup:192 %eh_info = landingpad { ptr, i32 }193 cleanup194 call void @"StreamingCleanup::~StreamingCleanup"(ptr %cleanup)195 resume { ptr, i32 } %eh_info196}197 198declare i32 @__gxx_personality_v0(...)199