From 3ade8cb0e7768207624913d5d9abdf7f13c5c404 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Tue, 15 Jul 2025 15:15:27 -0700 Subject: [PATCH 1/3] [MachineOutliner] Avoid ranges that cross bundle boundary --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 11 +++-- .../machine-outliner-safe-range-in-middle.mir | 49 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 5420545cc3cec..a23ed60d0325b 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -9585,10 +9585,13 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB, }; auto SaveRangeIfNonEmpty = [&RangeLen, &Ranges, &RangeBegin, &RangeEnd]() { // At least one unsafe register is not dead. We do not want to outline at - // this point. If it is long enough to outline from, save the range - // [RangeBegin, RangeEnd). - if (RangeLen > 1) - Ranges.push_back(std::make_pair(RangeBegin, RangeEnd)); + // this point. If it is long enough to outline from and does not cross a + // bundle boundary, save the range [RangeBegin, RangeEnd). + if (RangeLen <= 1) + return; + if (RangeBegin->isBundledWithPred()) + return; + Ranges.push_back(std::make_pair(RangeBegin, RangeEnd)); }; // Find the first point where all unsafe registers are dead. // FIND: <-- end of first potential range diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir b/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir index 23811425101fd..ed4a8fe76c221 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir @@ -40,3 +40,52 @@ body: | $x9 = ADDXri $x9, 16, 0 $x16 = ADDXri killed $x16, 16, 0 RET undef $x9 +... +--- +name: unsafe_range_bundle +tracksRegLiveness: true +machineFunctionInfo: + hasRedZone: false +body: | + bb.0: + liveins: $x0 + ; Begin safe range of 3 instructions + ; CHECK-LABEL: name: unsafe_range_bundle + ; CHECK: liveins: $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x0, implicit-def $x1, implicit-def $x2, implicit-def $x3, implicit-def $x16, implicit $x0, implicit $sp + ; CHECK-NEXT: $x9 = ADDXri $x16, 16, 0 + ; CHECK-NEXT: BUNDLE { + ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 + ; CHECK-NEXT: $x0 = ADDXri $x0, 0, 0 + ; CHECK-NEXT: $x1 = ADDXri $x0, 1, 0 + ; CHECK-NEXT: } + ; CHECK-NEXT: $x2 = ADDXri $x0, 2, 0 + ; CHECK-NEXT: $x3 = ADDXri $x0, 3, 0 + ; CHECK-NEXT: $x16 = ADDXri $x0, 16, 0 + ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0 + ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 + ; CHECK-NEXT: RET undef $x9 + $x0 = ADDXri $x0, 0, 0 + $x1 = ADDXri $x0, 1, 0 + $x2 = ADDXri $x0, 2, 0 + $x3 = ADDXri $x0, 3, 0 + + ; End safe range + $x16 = ADDXri $x0, 16, 0 + $x9 = ADDXri $x16, 16, 0 + ; Bundle crosses a safe range + BUNDLE { + $x16 = ADDXri killed $x16, 16, 0 + + $x0 = ADDXri $x0, 0, 0 + $x1 = ADDXri $x0, 1, 0 + } + $x2 = ADDXri $x0, 2, 0 + $x3 = ADDXri $x0, 3, 0 + ; End safe range + $x16 = ADDXri $x0, 16, 0 + $x9 = ADDXri $x9, 16, 0 + $x16 = ADDXri killed $x16, 16, 0 + RET undef $x9 + From 543cde89da47765c267182ae7d7a494da934cc9b Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Tue, 15 Jul 2025 15:23:42 -0700 Subject: [PATCH 2/3] be fancy --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index a23ed60d0325b..0c8af2058963b 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -9591,7 +9591,7 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB, return; if (RangeBegin->isBundledWithPred()) return; - Ranges.push_back(std::make_pair(RangeBegin, RangeEnd)); + Ranges.emplace_back(RangeBegin, RangeEnd); }; // Find the first point where all unsafe registers are dead. // FIND: <-- end of first potential range From fcac6311dbaebc957bbc52ab43979ec32db3b932 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Wed, 16 Jul 2025 09:35:45 -0700 Subject: [PATCH 3/3] Fix test and add extra check --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 4 +- .../machine-outliner-safe-range-in-middle.mir | 53 ++++++------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 0c8af2058963b..9a8e9294aa861 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -9589,7 +9589,9 @@ AArch64InstrInfo::getOutlinableRanges(MachineBasicBlock &MBB, // bundle boundary, save the range [RangeBegin, RangeEnd). if (RangeLen <= 1) return; - if (RangeBegin->isBundledWithPred()) + if (!RangeBegin.isEnd() && RangeBegin->isBundledWithPred()) + return; + if (!RangeEnd.isEnd() && RangeEnd->isBundledWithPred()) return; Ranges.emplace_back(RangeBegin, RangeEnd); }; diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir b/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir index ed4a8fe76c221..b99ca25a5432d 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-safe-range-in-middle.mir @@ -16,29 +16,27 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x0, implicit-def $x1, implicit-def $x2, implicit-def $x3, implicit-def $x16, implicit $x0, implicit $sp ; CHECK-NEXT: $x9 = ADDXri $x16, 16, 0 - ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 + ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 1 ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x0, implicit-def $x1, implicit-def $x2, implicit-def $x3, implicit-def $x16, implicit $x0, implicit $sp ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0 - ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 + ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 2 ; CHECK-NEXT: RET undef $x9 $x0 = ADDXri $x0, 0, 0 $x1 = ADDXri $x0, 1, 0 $x2 = ADDXri $x0, 2, 0 $x3 = ADDXri $x0, 3, 0 - - ; End safe range $x16 = ADDXri $x0, 16, 0 $x9 = ADDXri $x16, 16, 0 - $x16 = ADDXri killed $x16, 16, 0 - + $x16 = ADDXri killed $x16, 16, 1 + ; End safe range $x0 = ADDXri $x0, 0, 0 $x1 = ADDXri $x0, 1, 0 $x2 = ADDXri $x0, 2, 0 $x3 = ADDXri $x0, 3, 0 - ; End safe range $x16 = ADDXri $x0, 16, 0 $x9 = ADDXri $x9, 16, 0 - $x16 = ADDXri killed $x16, 16, 0 + $x16 = ADDXri killed $x16, 16, 2 + ; End safe range RET undef $x9 ... --- @@ -49,43 +47,22 @@ machineFunctionInfo: body: | bb.0: liveins: $x0 - ; Begin safe range of 3 instructions ; CHECK-LABEL: name: unsafe_range_bundle ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x0, implicit-def $x1, implicit-def $x2, implicit-def $x3, implicit-def $x16, implicit $x0, implicit $sp - ; CHECK-NEXT: $x9 = ADDXri $x16, 16, 0 + ; CHECK-NEXT: $x0 = ADDXri $x0, 0, 0 + ; CHECK-NEXT: $x16 = ADDXri $x0, 16, 0 ; CHECK-NEXT: BUNDLE { - ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 - ; CHECK-NEXT: $x0 = ADDXri $x0, 0, 0 - ; CHECK-NEXT: $x1 = ADDXri $x0, 1, 0 + ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 3 + ; CHECK-NEXT: $x1 = ADDXri $x0, 0, 0 ; CHECK-NEXT: } - ; CHECK-NEXT: $x2 = ADDXri $x0, 2, 0 - ; CHECK-NEXT: $x3 = ADDXri $x0, 3, 0 - ; CHECK-NEXT: $x16 = ADDXri $x0, 16, 0 - ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0 - ; CHECK-NEXT: $x16 = ADDXri killed $x16, 16, 0 ; CHECK-NEXT: RET undef $x9 $x0 = ADDXri $x0, 0, 0 - $x1 = ADDXri $x0, 1, 0 - $x2 = ADDXri $x0, 2, 0 - $x3 = ADDXri $x0, 3, 0 - - ; End safe range $x16 = ADDXri $x0, 16, 0 - $x9 = ADDXri $x16, 16, 0 - ; Bundle crosses a safe range - BUNDLE { - $x16 = ADDXri killed $x16, 16, 0 - - $x0 = ADDXri $x0, 0, 0 - $x1 = ADDXri $x0, 1, 0 + BUNDLE { ; Bundle crosses a safe range + $x16 = ADDXri killed $x16, 16, 3 + ; End safe range + $x1 = ADDXri $x0, 0, 0 } - $x2 = ADDXri $x0, 2, 0 - $x3 = ADDXri $x0, 3, 0 - ; End safe range - $x16 = ADDXri $x0, 16, 0 - $x9 = ADDXri $x9, 16, 0 - $x16 = ADDXri killed $x16, 16, 0 RET undef $x9 - +...