Skip to content

Commit de37da8

Browse files
authored
[MachineOutliner] Preserve instruction bundles (#106402)
When the machine outliner copies instructions from a source function into an outlined function, it was doing it using `CloneMachineInstr`, which is documented as not preserving the interior of any instruction bundle. So outlining code that includes an instruction bundle would fail, because in the outlined version, the bundle would be empty, so instructions would go missing in the move. This occurs when any bundled instruction appears in the outlined code, so there was no need to construct an unusual test case: I've just copied a function from the existing `stp-opt-with-renaming.mir`, which happens to contain an SVE instruction bundle. Including two identical copies of that function makes the outliner merge them, and then we check that it didn't destroy the interior of the bundle in the process.
1 parent 4bccb01 commit de37da8

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

llvm/lib/CodeGen/MachineOutliner.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -763,10 +763,9 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
763763
BuildMI(MBB, MBB.end(), DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
764764
.addCFIIndex(MF.addFrameInst(CFI));
765765
} else {
766-
MachineInstr *NewMI = MF.CloneMachineInstr(&MI);
767-
NewMI->dropMemRefs(MF);
768-
NewMI->setDebugLoc(DL);
769-
MBB.insert(MBB.end(), NewMI);
766+
MachineInstr &NewMI = TII.duplicate(MBB, MBB.end(), MI);
767+
NewMI.dropMemRefs(MF);
768+
NewMI.setDebugLoc(DL);
770769
}
771770
}
772771

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# RUN: llc -mtriple=aarch64 -run-pass=machine-outliner \
2+
# RUN: -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
# CHECK: name: OUTLINED_FUNCTION_0
5+
# CHECK-NOT: name:
6+
# CHECK: BUNDLE implicit-def $z3, implicit-def $q3, implicit-def $d3, implicit-def $s3, implicit-def $h3, implicit-def $b3, implicit $z19, implicit $p0, implicit $z16 {
7+
# CHECK: $z3 = MOVPRFX_ZZ $z19
8+
# CHECK: $z3 = FMUL_ZPmZ_S renamable $p0, killed $z3, renamable $z16
9+
# CHECK: }
10+
11+
---
12+
name: bundled
13+
alignment: 4
14+
tracksRegLiveness: true
15+
frameInfo:
16+
maxAlignment: 1
17+
maxCallFrameSize: 0
18+
machineFunctionInfo:
19+
hasRedZone: false
20+
body: |
21+
bb.0.entry:
22+
liveins: $z3, $z19, $p0, $z16
23+
renamable $q0 = LDRQui $sp, 1 :: (load 16)
24+
STRSui renamable $s0, $sp, 9, implicit killed $q0 :: (store (s32))
25+
BUNDLE implicit-def $z3, implicit-def $q3, implicit-def $d3, implicit-def $s3, implicit-def $h3, implicit-def $b3, implicit $z19, implicit $p0, implicit $z16 {
26+
$z3 = MOVPRFX_ZZ $z19
27+
$z3 = FMUL_ZPmZ_S renamable $p0, killed $z3, renamable $z16
28+
}
29+
renamable $q0 = LDRQui $sp, 0 :: (load 16, align 32)
30+
STRSui renamable $s0, $sp, 10, implicit killed $q0 :: (store (s32))
31+
RET undef $lr
32+
...
33+
---
34+
name: bundled_clone
35+
alignment: 4
36+
tracksRegLiveness: true
37+
frameInfo:
38+
maxAlignment: 1
39+
maxCallFrameSize: 0
40+
machineFunctionInfo:
41+
hasRedZone: false
42+
body: |
43+
bb.0.entry:
44+
liveins: $z3, $z19, $p0, $z16
45+
renamable $q0 = LDRQui $sp, 1 :: (load 16)
46+
STRSui renamable $s0, $sp, 9, implicit killed $q0 :: (store (s32))
47+
BUNDLE implicit-def $z3, implicit-def $q3, implicit-def $d3, implicit-def $s3, implicit-def $h3, implicit-def $b3, implicit $z19, implicit $p0, implicit $z16 {
48+
$z3 = MOVPRFX_ZZ $z19
49+
$z3 = FMUL_ZPmZ_S renamable $p0, killed $z3, renamable $z16
50+
}
51+
renamable $q0 = LDRQui $sp, 0 :: (load 16, align 32)
52+
STRSui renamable $s0, $sp, 10, implicit killed $q0 :: (store (s32))
53+
RET undef $lr
54+
...

0 commit comments

Comments
 (0)