diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1272,7 +1272,8 @@ // Make sure the operands don't reference something unsafe. for (const auto &MO : MI.operands()) - if (MO.isMBB() || MO.isBlockAddress() || MO.isCPI() || MO.isJTI()) + if (MO.isMBB() || MO.isBlockAddress() || MO.isCPI() || MO.isJTI() || + MO.isCFIIndex() || MO.isFI() || MO.isTargetIndex()) return outliner::InstrType::Illegal; // Don't allow instructions which won't be materialized to impact outlining diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-frame-index.mir b/llvm/test/CodeGen/RISCV/machine-outliner-frame-index.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/machine-outliner-frame-index.mir @@ -0,0 +1,111 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv32 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \ +# RUN: | FileCheck -check-prefix=RV32I-MO %s +# RUN: llc -march=riscv64 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \ +# RUN: | FileCheck -check-prefix=RV64I-MO %s + +# Ensure that we won't outline candidates which contains frame indexes. + +--- | + define void @func1(i32 %a, i32 %b) { ret void } + + define void @func2(i32 %a, i32 %b) { ret void } + + define void @func3(i32 %a, i32 %b) { ret void } +... +--- +name: func1 +tracksRegLiveness: true +fixedStack: + - { id: 0, type: default, size: 4} +stack: + - { id: 0, type: default, size: 4} +body: | + bb.0: + liveins: $x10, $x11 + ; RV32I-MO-LABEL: name: func1 + ; RV32I-MO: liveins: $x10, $x11 + ; RV32I-MO-NEXT: {{ $}} + ; RV32I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV32I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV32I-MO-NEXT: PseudoRET + ; RV64I-MO-LABEL: name: func1 + ; RV64I-MO: liveins: $x10, $x11 + ; RV64I-MO-NEXT: {{ $}} + ; RV64I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV64I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV64I-MO-NEXT: PseudoRET + SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + $x11 = ORI $x11, 1023 + $x12 = ADDI $x10, 17 + $x11 = AND $x12, $x11 + $x10 = SUB $x10, $x11 + SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + PseudoRET +... +--- +name: func2 +tracksRegLiveness: true + +fixedStack: + - { id: 0, type: default, size: 4} +stack: + - { id: 0, type: default, size: 4} +body: | + bb.0: + liveins: $x10, $x11 + ; RV32I-MO-LABEL: name: func2 + ; RV32I-MO: liveins: $x10, $x11 + ; RV32I-MO-NEXT: {{ $}} + ; RV32I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV32I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV32I-MO-NEXT: PseudoRET + ; RV64I-MO-LABEL: name: func2 + ; RV64I-MO: liveins: $x10, $x11 + ; RV64I-MO-NEXT: {{ $}} + ; RV64I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV64I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV64I-MO-NEXT: PseudoRET + SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + $x11 = ORI $x11, 1023 + $x12 = ADDI $x10, 17 + $x11 = AND $x12, $x11 + $x10 = SUB $x10, $x11 + SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + PseudoRET +... +--- +name: func3 +tracksRegLiveness: true +fixedStack: + - { id: 0, type: default, size: 4} +stack: + - { id: 0, type: default, size: 4} +body: | + bb.0: + liveins: $x10, $x11 + ; RV32I-MO-LABEL: name: func3 + ; RV32I-MO: liveins: $x10, $x11 + ; RV32I-MO-NEXT: {{ $}} + ; RV32I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV32I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV32I-MO-NEXT: PseudoRET + ; RV64I-MO-LABEL: name: func3 + ; RV64I-MO: liveins: $x10, $x11 + ; RV64I-MO-NEXT: {{ $}} + ; RV64I-MO-NEXT: SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 + ; RV64I-MO-NEXT: SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + ; RV64I-MO-NEXT: PseudoRET + SD $x10, %fixed-stack.0, 0 :: (store (s32) into %fixed-stack.0) + $x11 = ORI $x11, 1023 + $x12 = ADDI $x10, 17 + $x11 = AND $x12, $x11 + $x10 = SUB $x10, $x11 + SD $x11, %stack.0, 0 :: (store (s32) into %stack.0) + PseudoRET