Index: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5188,6 +5188,12 @@ if (!MightNeedStackFixUp) return MachineOutlinerInstrType::Legal; + // Any modification of SP will break our code to save/restore LR. + // FIXME: We could handle some instructions which add a constant offset to + // SP, with a bit more work. + if (MI.modifiesRegister(AArch64::SP, &RI)) + return MachineOutlinerInstrType::Illegal; + // At this point, we have a stack instruction that we might need to fix // up. We'll handle it if it's a load or store. if (MI.mayLoadOrStore()) { @@ -5217,6 +5223,8 @@ return MachineOutlinerInstrType::Legal; } + // FIXME: Add handling for instructions like "add x0, sp, #8". + // We can't fix it up, so don't outline it. return MachineOutlinerInstrType::Illegal; } Index: llvm/trunk/test/CodeGen/AArch64/machine-outliner-remarks.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/machine-outliner-remarks.ll +++ llvm/trunk/test/CodeGen/AArch64/machine-outliner-remarks.ll @@ -4,9 +4,9 @@ ; CHECK-SAME: Instructions from outlining all occurrences (9) >= ; CHECK-SAME: Unoutlined instruction count (4) ; CHECK-SAME: (Also found at: machine-outliner-remarks.ll:13:9) -; CHECK: remark: :0:0: Saved 5 instructions by outlining 7 instructions -; CHECK-SAME: from 2 locations. (Found at: machine-outliner-remarks.ll:27:9, -; CHECK-SAME: machine-outliner-remarks.ll:36:1) +; CHECK: remark: :0:0: Saved 5 instructions by outlining 12 instructions +; CHECK-SAME: from 2 locations. (Found at: machine-outliner-remarks.ll:36:1, +; CHECK-SAME: machine-outliner-remarks.ll:27:9) ; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml ; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML ; YAML: --- !Missed @@ -40,17 +40,17 @@ ; YAML-NEXT: - OutliningBenefit: '5' ; YAML-NEXT: - String: ' instructions by ' ; YAML-NEXT: - String: 'outlining ' -; YAML-NEXT: - Length: '7' +; YAML-NEXT: - Length: '12' ; YAML-NEXT: - String: ' instructions ' ; YAML-NEXT: - String: 'from ' ; YAML-NEXT: - NumOccurrences: '2' ; YAML-NEXT: - String: ' locations. ' ; YAML-NEXT: - String: '(Found at: ' -; YAML-NEXT: - StartLoc0: 'machine-outliner-remarks.ll:27:9' -; YAML-NEXT: DebugLoc: { File: machine-outliner-remarks.ll, Line: 27, Column: 9 } -; YAML-NEXT: - String: ', ' -; YAML-NEXT: - StartLoc1: 'machine-outliner-remarks.ll:36:1' +; YAML-NEXT: - StartLoc0: 'machine-outliner-remarks.ll:36:1' ; YAML-NEXT: DebugLoc: { File: machine-outliner-remarks.ll, Line: 36, Column: 1 } +; YAML-NEXT: - String: ', ' +; YAML-NEXT: - StartLoc1: 'machine-outliner-remarks.ll:27:9' +; YAML-NEXT: DebugLoc: { File: machine-outliner-remarks.ll, Line: 27, Column: 9 } ; YAML-NEXT: - String: ')' define void @dog() #0 !dbg !8 { @@ -76,10 +76,14 @@ %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4, !dbg !24 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4, !dbg !26 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4, !dbg !24 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4, !dbg !26 ret void } @@ -88,10 +92,14 @@ %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4, !dbg !33 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4, !dbg !35 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4, !dbg !33 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4, !dbg !35 ret void } Index: llvm/trunk/test/CodeGen/AArch64/machine-outliner.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/machine-outliner.ll +++ llvm/trunk/test/CodeGen/AArch64/machine-outliner.ll @@ -6,15 +6,18 @@ ; CHECK-LABEL: _fish: ; CHECK-NOT: OUTLINED ; ODR: [[OUTLINED:OUTLINED_FUNCTION_[0-9]+]] - ; ODR-NOT: ret %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4 ret void } @@ -26,10 +29,14 @@ %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4 ret void } @@ -37,16 +44,18 @@ ; CHECK-LABEL: _cat: ; CHECK: [[OUTLINED:OUTLINED_FUNCTION_[0-9]+]] ; ODR: [[OUTLINED]] - ; CHECK-NOT: ret - ; ODR-NOT: ret %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4 ret void } @@ -54,28 +63,36 @@ ; CHECK-LABEL: _dog: ; CHECK: [[OUTLINED]] ; ODR: [[OUTLINED]] - ; CHECK-NOT: ret - ; ODR-NOT: ret %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - store i32 0, i32* %1, align 4 - store i32 1, i32* %2, align 4 - store i32 2, i32* %3, align 4 - store i32 3, i32* %4, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, i32* %1, align 4 + store i32 2, i32* %2, align 4 + store i32 3, i32* %3, align 4 + store i32 4, i32* %4, align 4 + store i32 5, i32* %5, align 4 + store i32 6, i32* %6, align 4 ret void } ; ODR: [[OUTLINED]]: ; CHECK: .p2align 2 ; CHECK-NEXT: [[OUTLINED]]: -; CHECK-DAG: orr w8, wzr, #0x1 -; CHECK-NEXT: stp w8, wzr, [sp, #8] -; CHECK-NEXT: orr w8, wzr, #0x2 -; CHECK-NEXT: str w8, [sp, #4] -; CHECK-NEXT: orr w8, wzr, #0x3 -; CHECK-NEXT: str w8, [sp], #16 +; CHECK: orr w8, wzr, #0x1 +; CHECK-NEXT: str w8, [sp, #44] +; CHECK-NEXT: orr w8, wzr, #0x2 +; CHECK-NEXT: str w8, [sp, #40] +; CHECK-NEXT: orr w8, wzr, #0x3 +; CHECK-NEXT: str w8, [sp, #36] +; CHECK-NEXT: orr w8, wzr, #0x4 +; CHECK-NEXT: str w8, [sp, #32] +; CHECK-NEXT: mov w8, #5 +; CHECK-NEXT: str w8, [sp, #28] +; CHECK-NEXT: orr w8, wzr, #0x6 +; CHECK-NEXT: str w8, [sp, #24] ; CHECK-NEXT: ret attributes #0 = { noredzone "target-cpu"="cyclone" }