+++ /dev/null
-//===-- CFIFixup.h - Insert CFI remember/restore instructions ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Contains definition of the base CFIFixup pass.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_CFIFIXUP_H
-#define LLVM_CODEGEN_CFIFIXUP_H
-
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/InitializePasses.h"
-
-namespace llvm {
-class CFIFixup : public MachineFunctionPass {
-public:
- static char ID;
-
- CFIFixup() : MachineFunctionPass(ID) {
- initializeCFIFixupPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-};
-} // namespace llvm
-
-#endif // LLVM_CODEGEN_CFIFIXUP_H
// This pass expands indirectbr instructions.
FunctionPass *createIndirectBrExpandPass();
- /// Creates CFI Fixup pass. \see CFIFixup.cpp
- FunctionPass *createCFIFixup();
-
/// Creates CFI Instruction Inserter pass. \see CFIInstrInserter.cpp
FunctionPass *createCFIInstrInserter();
emitCalleeSavedFrameMovesFullCFA(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) const {}
- /// Returns true if we may need to fix the unwind infportmation for the
- /// function.
- virtual bool enableCFIFixup(MachineFunction &MF) const;
-
- /// Emit CFI instructions that recreate the state of the unwind information
- /// upon fucntion entry.
- virtual void resetCFIToInitialState(MachineBasicBlock &MBB) const {}
-
/// Replace a StackProbe stub (if any) with the actual probe code inline
virtual void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const {}
void initializeCFGuardPass(PassRegistry&);
void initializeCFGuardLongjmpPass(PassRegistry&);
void initializeCFGViewerLegacyPassPass(PassRegistry&);
-void initializeCFIFixupPass(PassRegistry&);
void initializeCFIInstrInserterPass(PassRegistry&);
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
Options.SupportsDebugEntryValues = Enable;
}
- void setCFIFixup(bool Enable) { Options.EnableCFIFixup = Enable; }
-
bool getAIXExtendedAltivecABI() const {
return Options.EnableAIXExtendedAltivecABI;
}
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
XRayOmitFunctionIndex(false), DebugStrictDwarf(false),
Hotpatch(false), PPCGenScalarMASSEntries(false), JMCInstrument(false),
- EnableCFIFixup(false),
FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// Enable JustMyCode instrumentation.
unsigned JMCInstrument : 1;
- /// Enable the CFIFixup pass.
- unsigned EnableCFIFixup : 1;
-
/// Name of the stack usage file (i.e., .su file) if user passes
/// -fstack-usage. If empty, it can be implied that -fstack-usage is not
/// passed on the command line.
case MCCFIInstruction::OpUndefined:
OutStreamer->emitCFIUndefined(Inst.getRegister());
break;
- case MCCFIInstruction::OpRememberState:
- OutStreamer->emitCFIRememberState();
- break;
- case MCCFIInstruction::OpRestoreState:
- OutStreamer->emitCFIRestoreState();
- break;
}
}
+++ /dev/null
-//===------ CFIFixup.cpp - Insert CFI remember/restore instructions -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-
-// This pass inserts the necessary instructions to adjust for the inconsistency
-// of the call-frame information caused by final machine basic block layout.
-// The pass relies in constraints LLVM imposes on the placement of
-// save/restore points (cf. ShrinkWrap):
-// * there is a single basic block, containing the function prologue
-// * possibly multiple epilogue blocks, where each epilogue block is
-// complete and self-contained, i.e. CSR restore instructions (and the
-// corresponding CFI instructions are not split across two or more blocks.
-// * prologue and epilogue blocks are outside of any loops
-// Thus, during execution, at the beginning and at the end of each basic block
-// the function can be in one of two states:
-// - "has a call frame", if the function has executed the prologue, and
-// has not executed any epilogue
-// - "does not have a call frame", if the function has not executed the
-// prologue, or has executed an epilogue
-// which can be computed by a single RPO traversal.
-
-// In order to accommodate backends which do not generate unwind info in
-// epilogues we compute an additional property "strong no call frame on entry",
-// which is set for the entry point of the function and for every block
-// reachable from the entry along a path that does not execute the prologue. If
-// this property holds, it takes precedence over the "has a call frame"
-// property.
-
-// From the point of view of the unwind tables, the "has/does not have call
-// frame" state at beginning of each block is determined by the state at the end
-// of the previous block, in layout order. Where these states differ, we insert
-// compensating CFI instructions, which come in two flavours:
-
-// - CFI instructions, which reset the unwind table state to the initial one.
-// This is done by a target specific hook and is expected to be trivial
-// to implement, for example it could be:
-// .cfi_def_cfa <sp>, 0
-// .cfi_same_value <rN>
-// .cfi_same_value <rN-1>
-// ...
-// where <rN> are the callee-saved registers.
-// - CFI instructions, which reset the unwind table state to the one
-// created by the function prologue. These are
-// .cfi_restore_state
-// .cfi_remember_state
-// In this case we also insert a `.cfi_remember_state` after the last CFI
-// instruction in the function prologue.
-//
-// Known limitations:
-// * the pass cannot handle an epilogue preceding the prologue in the basic
-// block layout
-// * the pass does not handle functions where SP is used as a frame pointer and
-// SP adjustments up and down are done in different basic blocks (TODO)
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/CFIFixup.h"
-
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SmallBitVector.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCDwarf.h"
-#include "llvm/Target/TargetMachine.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "cfi-fixup"
-
-char CFIFixup::ID = 0;
-
-INITIALIZE_PASS(CFIFixup, "cfi-fixup",
- "Insert CFI remember/restore state instructions", false, false)
-FunctionPass *llvm::createCFIFixup() { return new CFIFixup(); }
-
-static bool isPrologueCFIInstruction(const MachineInstr &MI) {
- return MI.getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
- MI.getFlag(MachineInstr::FrameSetup);
-}
-
-static bool containsPrologue(const MachineBasicBlock &MBB) {
- return llvm::any_of(MBB.instrs(), isPrologueCFIInstruction);
-}
-
-static bool containsEpilogue(const MachineBasicBlock &MBB) {
- return llvm::any_of(llvm::reverse(MBB), [](const auto &MI) {
- return MI.getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
- MI.getFlag(MachineInstr::FrameDestroy);
- });
-}
-
-bool CFIFixup::runOnMachineFunction(MachineFunction &MF) {
- const TargetFrameLowering &TFL = *MF.getSubtarget().getFrameLowering();
- if (!TFL.enableCFIFixup(MF))
- return false;
-
- const unsigned NumBlocks = MF.getNumBlockIDs();
- if (NumBlocks < 2)
- return false;
-
- struct BlockFlags {
- bool StrongNoFrameOnEntry : 1;
- bool HasFrameOnEntry : 1;
- bool HasFrameOnExit : 1;
- };
- SmallVector<BlockFlags, 32> BlockInfo(NumBlocks, {false, false, false});
- BlockInfo[0].StrongNoFrameOnEntry = true;
-
- // Compute the presence/absence of frame at each basic block.
- MachineBasicBlock *PrologueBlock = nullptr;
- ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
- for (MachineBasicBlock *MBB : RPOT) {
- BlockFlags &Info = BlockInfo[MBB->getNumber()];
-
- // Set to true if the current block contains the prologue or the epilogue,
- // respectively.
- bool HasPrologue = false;
- bool HasEpilogue = false;
-
- if (!PrologueBlock && !Info.HasFrameOnEntry && containsPrologue(*MBB)) {
- PrologueBlock = MBB;
- HasPrologue = true;
- }
-
- if (Info.HasFrameOnEntry || HasPrologue)
- HasEpilogue = containsEpilogue(*MBB);
-
- // If the function has a call frame at the entry of the current block or the
- // current block contains the prologue, then the function has a call frame
- // at the exit of the block, unless the block contains the epilogue.
- Info.HasFrameOnExit = (Info.HasFrameOnEntry || HasPrologue) && !HasEpilogue;
-
- // Set the successors' state on entry.
- for (MachineBasicBlock *Succ : MBB->successors()) {
- BlockFlags &SuccInfo = BlockInfo[Succ->getNumber()];
- SuccInfo.StrongNoFrameOnEntry |=
- Info.StrongNoFrameOnEntry && !HasPrologue;
- SuccInfo.HasFrameOnEntry = Info.HasFrameOnExit;
- }
- }
-
- if (!PrologueBlock)
- return false;
-
- // Walk the blocks of the function in "physical" order.
- // Every block inherits the frame state (as recorded in the unwind tables)
- // of the previous block. If the intended frame state is different, insert
- // compensating CFI instructions.
- const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
- bool Change = false;
- // `InsertPt` always points to the point in a preceding block where we have to
- // insert a `.cfi_remember_state`, in the case that the current block needs a
- // `.cfi_restore_state`.
- MachineBasicBlock *InsertMBB = PrologueBlock;
- MachineBasicBlock::iterator InsertPt = PrologueBlock->begin();
- for (MachineInstr &MI : *PrologueBlock)
- if (isPrologueCFIInstruction(MI))
- InsertPt = std::next(MI.getIterator());
-
- assert(InsertPt != PrologueBlock->begin() &&
- "Inconsistent notion of \"prologue block\"");
-
- // No point starting before the prologue block.
- // TODO: the unwind tables will still be incorrect if an epilogue physically
- // preceeds the prologue.
- MachineFunction::iterator CurrBB = std::next(PrologueBlock->getIterator());
- bool HasFrame = BlockInfo[PrologueBlock->getNumber()].HasFrameOnExit;
- while (CurrBB != MF.end()) {
- auto &Info = BlockInfo[CurrBB->getNumber()];
-#ifndef NDEBUG
- if (!Info.StrongNoFrameOnEntry) {
- for (auto *Pred : CurrBB->predecessors())
- assert(Info.HasFrameOnEntry ==
- BlockInfo[Pred->getNumber()].HasFrameOnExit &&
- "Inconsistent call frame state");
- }
-#endif
- if (!Info.StrongNoFrameOnEntry && Info.HasFrameOnEntry && !HasFrame) {
- // Reset to the "after prologue" state.
-
- // Insert a `.cfi_remember_state` into the last block known to have a
- // stack frame.
- unsigned CFIIndex =
- MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
- BuildMI(*InsertMBB, InsertPt, DebugLoc(),
- TII.get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- // Insert a `.cfi_restore_state` at the beginning of the current block.
- CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
- InsertPt = BuildMI(*CurrBB, CurrBB->begin(), DebugLoc(),
- TII.get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- ++InsertPt;
- InsertMBB = &*CurrBB;
- Change = true;
- } else if ((Info.StrongNoFrameOnEntry || !Info.HasFrameOnEntry) &&
- HasFrame) {
- // Reset to the state upon function entry.
- TFL.resetCFIToInitialState(*CurrBB);
- Change = true;
- }
-
- HasFrame = Info.HasFrameOnExit;
- ++CurrBB;
- }
-
- return Change;
-}
CalcSpillWeights.cpp
CallingConvLower.cpp
CFGuardLongjmp.cpp
- CFIFixup.cpp
CFIInstrInserter.cpp
CodeGen.cpp
CodeGenCommonISel.cpp
initializeBranchFolderPassPass(Registry);
initializeBranchRelaxationPass(Registry);
initializeCFGuardLongjmpPass(Registry);
- initializeCFIFixupPass(Registry);
initializeCFIInstrInserterPass(Registry);
initializeCheckDebugMachineModulePass(Registry);
initializeCodeGenPreparePass(Registry);
// Allow duplication of CFI instructions.
if (MI->isCFIInstruction()) {
BuildMI(*PredBB, PredBB->end(), PredBB->findDebugLoc(PredBB->begin()),
- TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(MI->getOperand(0).getCFIIndex())
- .setMIFlags(MI->getFlags());
+ TII->get(TargetOpcode::CFI_INSTRUCTION)).addCFIIndex(
+ MI->getOperand(0).getCFIIndex());
return;
}
MachineInstr &NewMI = TII->duplicate(*PredBB, PredBB->end(), *MI);
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
return false;
}
-bool TargetFrameLowering::enableCFIFixup(MachineFunction &MF) const {
- return MF.needsFrameMoves() &&
- !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
-}
-
/// Returns the displacement from the frame register to the stack
/// frame of the specified index, along with the frame register used
/// (in output arg FrameReg). This is the default implementation which
"Disable all outlining"),
// Sentinel value for unspecified option.
clEnumValN(RunOutliner::AlwaysOutline, "", "")));
-// Disable the pass to fix unwind information. Whether the pass is included in
-// the pipeline is controlled via the target options, this option serves as
-// manual override.
-static cl::opt<bool> DisableCFIFixup("disable-cfi-fixup", cl::Hidden,
- cl::desc("Disable the CFI fixup pass"));
// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
// able to enable or disable fast-isel independently from -O0.
addPass(createMachineFunctionSplitterPass());
}
- if (!DisableCFIFixup && TM->Options.EnableCFIFixup)
- addPass(createCFIFixup());
-
// Add passes that directly emit MI after all other MI passes.
addPreEmitPass2();
void initializeAArch64A57FPLoadBalancingPass(PassRegistry&);
void initializeAArch64AdvSIMDScalarPass(PassRegistry&);
void initializeAArch64BranchTargetsPass(PassRegistry&);
-void initializeAArch64CFIFixupPass(PassRegistry&);
void initializeAArch64CollectLOHPass(PassRegistry&);
void initializeAArch64CondBrTuningPass(PassRegistry &);
void initializeAArch64CompressJumpTablesPass(PassRegistry&);
static bool produceCompactUnwindFrame(MachineFunction &MF);
static bool needsWinCFI(const MachineFunction &MF);
static StackOffset getSVEStackSize(const MachineFunction &MF);
-static bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF);
/// Returns true if a homogeneous prolog or epilog code can be emitted
/// for the size optimization. If possible, a frame helper call is injected.
emitCalleeSavedSVELocations(MBB, MBBI);
}
-static void insertCFISameValue(const MCInstrDesc &Desc, MachineFunction &MF,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator InsertPt,
- unsigned DwarfReg) {
- unsigned CFIIndex =
- MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, DwarfReg));
- BuildMI(MBB, InsertPt, DebugLoc(), Desc).addCFIIndex(CFIIndex);
-}
-
-void AArch64FrameLowering::resetCFIToInitialState(
- MachineBasicBlock &MBB) const {
-
- MachineFunction &MF = *MBB.getParent();
- const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
- const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
- const auto &TRI =
- static_cast<const AArch64RegisterInfo &>(*Subtarget.getRegisterInfo());
- const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
-
- const MCInstrDesc &CFIDesc = TII.get(TargetOpcode::CFI_INSTRUCTION);
- DebugLoc DL;
-
- // Reset the CFA to `SP + 0`.
- MachineBasicBlock::iterator InsertPt = MBB.begin();
- unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
- nullptr, TRI.getDwarfRegNum(AArch64::SP, true), 0));
- BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex);
-
- // Flip the RA sign state.
- if (MFI.shouldSignReturnAddress()) {
- CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
- BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex);
- }
-
- // Shadow call stack uses X18, reset it.
- if (needsShadowCallStackPrologueEpilogue(MF))
- insertCFISameValue(CFIDesc, MF, MBB, InsertPt,
- TRI.getDwarfRegNum(AArch64::X18, true));
-
- // Emit .cfi_same_value for callee-saved registers.
- const std::vector<CalleeSavedInfo> &CSI =
- MF.getFrameInfo().getCalleeSavedInfo();
- for (const auto &Info : CSI) {
- unsigned Reg = Info.getReg();
- if (!TRI.regNeedsCFI(Reg, Reg))
- continue;
- insertCFISameValue(CFIDesc, MF, MBB, InsertPt,
- TRI.getDwarfRegNum(Reg, true));
- }
-}
-
// Find a scratch register that we can use at the start of the prologue to
// re-align the stack pointer. We avoid using callee-save registers since they
// may appear to be free when this is called from canUseAsPrologue (during
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) const;
- void resetCFIToInitialState(MachineBasicBlock &MBB) const override;
-
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/CFIFixup.h"
#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
// AArch64 supports the debug entry values.
setSupportsDebugEntryValues(true);
-
- // AArch64 supports fixing up the DWARF unwind information.
- if (!getMCAsmInfo()->usesWindowsCFI())
- setCFIFixup(true);
}
AArch64TargetMachine::~AArch64TargetMachine() = default;
; CHECK-NEXT: Contiguously Lay Out Funclets
; CHECK-NEXT: StackMap Liveness Analysis
; CHECK-NEXT: Live DEBUG_VALUE analysis
-; CHECK-NEXT: Insert CFI remember/restore state instructions
; CHECK-NEXT: Unpack machine instruction bundles
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine Optimization Remark Emitter
; CHECK-NEXT: Live DEBUG_VALUE analysis
; CHECK-NEXT: Machine Outliner
; CHECK-NEXT: FunctionPass Manager
-; CHECK-NEXT: Insert CFI remember/restore state instructions
; CHECK-NEXT: Unpack machine instruction bundles
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine Optimization Remark Emitter
}
-define dso_local i32 @test_br_cc() uwtable {
+define dso_local i32 @test_br_cc() {
; CHECK-LABEL: test_br_cc:
; CHECK: // %bb.0:
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; HOTNESS-NEXT: Executing Pass 'Function Pass Manager'
; HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code'
-; HOTNESS-NEXT: Executing Pass 'Insert CFI remember/restore state instructions' on Function 'empty_func'
-; HOTNESS-NEXT: Freeing Pass 'Insert CFI remember/restore state instructions' on Function 'empty_func'
-; HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
-; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code'
; HOTNESS-NEXT: Executing Pass 'Unpack machine instruction bundles'
; HOTNESS-NEXT: Freeing Pass 'Unpack machine instruction bundles'
; HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
; NO_HOTNESS-NEXT: Executing Pass 'Function Pass Manager'
; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code'
-; NO_HOTNESS-NEXT: Executing Pass 'Insert CFI remember/restore state instructions' on Function 'empty_func'
-; NO_HOTNESS-NEXT: Freeing Pass 'Insert CFI remember/restore state instructions' on Function 'empty_func'
-; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
-; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code'
; NO_HOTNESS-NEXT: Executing Pass 'Unpack machine instruction bundles'
; NO_HOTNESS-NEXT: Freeing Pass 'Unpack machine instruction bundles'
; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code'
; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
; ENABLE-NEXT: add sp, sp, #32
; ENABLE-NEXT: LBB0_2: ; %false
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w30
-; ENABLE-NEXT: .cfi_same_value w29
; ENABLE-NEXT: ret
;
; DISABLE-LABEL: foo:
; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB1_4: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w30
-; ENABLE-NEXT: .cfi_same_value w29
-; ENABLE-NEXT: .cfi_same_value w19
-; ENABLE-NEXT: .cfi_same_value w20
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB3_4: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w30
-; ENABLE-NEXT: .cfi_same_value w29
-; ENABLE-NEXT: .cfi_same_value w19
-; ENABLE-NEXT: .cfi_same_value w20
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB4_4: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w30
-; ENABLE-NEXT: .cfi_same_value w29
-; ENABLE-NEXT: .cfi_same_value w19
-; ENABLE-NEXT: .cfi_same_value w20
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
; ENABLE-NEXT: add sp, sp, #16
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB6_4: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
; ENABLE-NEXT: ldp x20, x19, [sp], #16 ; 16-byte Folded Reload
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB7_4: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w19
-; ENABLE-NEXT: .cfi_same_value w20
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
; ENABLE-NEXT: add sp, sp, #64
; ENABLE-NEXT: ret
; ENABLE-NEXT: LBB8_2: ; %if.else
-; ENABLE-NEXT: .cfi_def_cfa wsp, 0
-; ENABLE-NEXT: .cfi_same_value w30
-; ENABLE-NEXT: .cfi_same_value w29
; ENABLE-NEXT: lsl w0, w1, #1
; ENABLE-NEXT: ret
;
+++ /dev/null
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64 -run-pass=cfi-fixup %s -o - | FileCheck %s
---- |
- define i32 @f0(i32 %x) #0 {
- entry: br label %return
- if.end: br label %return
- if.then2: br label %return
- if.else: br label %return
- return:
- ret i32 0
- }
-
- define i32 @f1(i32 %x) #0 {
- entry: br label %return
- if.end: br label %return
- if.then2: br label %return
- if.else: br label %return
- return:
- ret i32 0
- }
-
- define i32 @f2(i32 %x) #0 {
- entry: br label %return
- if.end: br label %return
- if.then2: br label %return
- if.else: br label %return
- return:
- ret i32 0
- }
-
- declare i32 @g(i32)
-
- attributes #0 = { nounwind shadowcallstack uwtable "sign-return-address"="non-leaf" "target-features"="+reserve-x18" }
-
-...
----
-name: f0
-alignment: 4
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-hasWinCFI: false
-failsVerification: false
-registers: []
-liveins:
- - { reg: '$w0', virtual-reg: '' }
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 16
- offsetAdjustment: 0
- maxAlignment: 16
- adjustsStack: true
- hasCalls: true
- stackProtector: ''
- maxCallFrameSize: 0
- cvBytesOfCalleeSavedRegisters: 0
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- hasTailCall: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack: []
-stack:
- - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
- stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-callSites: []
-debugValueSubstitutions: []
-constants: []
-machineFunctionInfo:
- hasRedZone: false
-body: |
- ; CHECK-LABEL: name: f0
- ; CHECK: bb.0.entry:
- ; CHECK-NEXT: successors: %bb.4(0x30000000), %bb.1(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CBZW renamable $w0, %bb.4
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.1.if.end:
- ; CHECK-NEXT: successors: %bb.3(0x30000000), %bb.2(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- ; CHECK-NEXT: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w30, -16
- ; CHECK-NEXT: CFI_INSTRUCTION remember_state
- ; CHECK-NEXT: TBNZW renamable $w0, 31, %bb.3
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.2.if.else:
- ; CHECK-NEXT: successors: %bb.5(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w8 = MOVZWi 1, 0
- ; CHECK-NEXT: $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- ; CHECK-NEXT: B %bb.5
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.3.if.then2:
- ; CHECK-NEXT: successors: %bb.5(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: B %bb.5
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.4.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CFI_INSTRUCTION def_cfa $wsp, 0
- ; CHECK-NEXT: CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: CFI_INSTRUCTION same_value $w18
- ; CHECK-NEXT: CFI_INSTRUCTION same_value $w30
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.5.return:
- ; CHECK-NEXT: successors: %bb.7(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CFI_INSTRUCTION restore_state
- ; CHECK-NEXT: CFI_INSTRUCTION remember_state
- ; CHECK-NEXT: B %bb.7
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.6.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
- ; CHECK-NEXT: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $w18
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $w30
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.7.return:
- ; CHECK-NEXT: successors: %bb.6(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CFI_INSTRUCTION restore_state
- ; CHECK-NEXT: B %bb.6
- bb.0.entry:
- successors: %bb.4(0x30000000), %bb.1(0x50000000)
- liveins: $w0, $lr, $x18
-
- CBZW renamable $w0, %bb.4
-
- bb.1.if.end:
- successors: %bb.3(0x30000000), %bb.2(0x50000000)
- liveins: $w0, $lr, $x18
-
- early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- frame-setup CFI_INSTRUCTION negate_ra_sign_state
- early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- frame-setup CFI_INSTRUCTION def_cfa_offset 16
- frame-setup CFI_INSTRUCTION offset $w30, -16
- TBNZW renamable $w0, 31, %bb.3
-
- bb.2.if.else:
- successors: %bb.5(0x80000000)
- liveins: $w0
-
- renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w8 = MOVZWi 1, 0
- $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- B %bb.5
-
- bb.3.if.then2:
- successors: %bb.5(0x80000000)
- liveins: $w0
-
- renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- B %bb.5
-
- bb.4.return:
- liveins: $w0
- RET undef $lr, implicit killed $w0
-
- bb.5.return:
- liveins: $w0
- B %bb.6
-
- bb.7.return:
- liveins: $w0
- early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- frame-destroy CFI_INSTRUCTION def_cfa_offset 0
- frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- frame-destroy CFI_INSTRUCTION negate_ra_sign_state
- early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- frame-destroy CFI_INSTRUCTION restore $w18
- frame-destroy CFI_INSTRUCTION restore $w30
- RET undef $lr, implicit killed $w0
-
- bb.6.return:
- liveins: $w0
- B %bb.7
-
-
-...
----
-name: f1
-alignment: 4
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-hasWinCFI: false
-failsVerification: false
-registers: []
-liveins:
- - { reg: '$w0', virtual-reg: '' }
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 16
- offsetAdjustment: 0
- maxAlignment: 16
- adjustsStack: true
- hasCalls: true
- stackProtector: ''
- maxCallFrameSize: 0
- cvBytesOfCalleeSavedRegisters: 0
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- hasTailCall: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack: []
-stack:
- - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
- stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-callSites: []
-debugValueSubstitutions: []
-constants: []
-machineFunctionInfo:
- hasRedZone: false
-body: |
- ; CHECK-LABEL: name: f1
- ; CHECK: bb.0.entry:
- ; CHECK-NEXT: successors: %bb.5(0x30000000), %bb.1(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CBZW renamable $w0, %bb.5
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.1.if.end:
- ; CHECK-NEXT: successors: %bb.3(0x30000000), %bb.2(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- ; CHECK-NEXT: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w30, -16
- ; CHECK-NEXT: TBNZW renamable $w0, 31, %bb.3
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.2.if.else:
- ; CHECK-NEXT: successors: %bb.4(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w8 = MOVZWi 1, 0
- ; CHECK-NEXT: $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- ; CHECK-NEXT: B %bb.4
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.3.if.then2:
- ; CHECK-NEXT: successors: %bb.4(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: B %bb.4
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.4.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
- ; CHECK-NEXT: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $w18
- ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $w30
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.5.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- bb.0.entry:
- successors: %bb.5(0x30000000), %bb.1(0x50000000)
- liveins: $w0, $lr, $x18
-
- CBZW renamable $w0, %bb.5
-
- bb.1.if.end:
- successors: %bb.3(0x30000000), %bb.2(0x50000000)
- liveins: $w0, $lr, $x18
-
- early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- frame-setup CFI_INSTRUCTION negate_ra_sign_state
- early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- frame-setup CFI_INSTRUCTION def_cfa_offset 16
- frame-setup CFI_INSTRUCTION offset $w30, -16
- TBNZW renamable $w0, 31, %bb.3
-
- bb.2.if.else:
- successors: %bb.4(0x80000000)
- liveins: $w0
-
- renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w8 = MOVZWi 1, 0
- $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- B %bb.4
-
- bb.3.if.then2:
- successors: %bb.4(0x80000000)
- liveins: $w0
-
- renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- B %bb.4
-
- bb.4.return:
- liveins: $w0
-
- early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- frame-destroy CFI_INSTRUCTION def_cfa_offset 0
- frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- frame-destroy CFI_INSTRUCTION negate_ra_sign_state
- early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- frame-destroy CFI_INSTRUCTION restore $w18
- frame-destroy CFI_INSTRUCTION restore $w30
- RET undef $lr, implicit killed $w0
-
- bb.5.return:
- liveins: $w0
- RET undef $lr, implicit killed $w0
-
-...
----
-name: f2
-alignment: 4
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-hasWinCFI: false
-failsVerification: false
-registers: []
-liveins:
- - { reg: '$w0', virtual-reg: '' }
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 16
- offsetAdjustment: 0
- maxAlignment: 16
- adjustsStack: true
- hasCalls: true
- stackProtector: ''
- maxCallFrameSize: 0
- cvBytesOfCalleeSavedRegisters: 0
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- hasTailCall: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack: []
-stack:
- - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
- stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-callSites: []
-debugValueSubstitutions: []
-constants: []
-machineFunctionInfo:
- hasRedZone: false
-body: |
- ; CHECK-LABEL: name: f2
- ; CHECK: bb.0.entry:
- ; CHECK-NEXT: successors: %bb.5(0x30000000), %bb.1(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CBZW renamable $w0, %bb.5
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.1.if.end:
- ; CHECK-NEXT: successors: %bb.3(0x30000000), %bb.2(0x50000000)
- ; CHECK-NEXT: liveins: $w0, $lr, $x18
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- ; CHECK-NEXT: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
- ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w30, -16
- ; CHECK-NEXT: TBNZW renamable $w0, 31, %bb.3
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.2.if.else:
- ; CHECK-NEXT: successors: %bb.4(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w8 = MOVZWi 1, 0
- ; CHECK-NEXT: $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- ; CHECK-NEXT: B %bb.4
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.3.if.then2:
- ; CHECK-NEXT: successors: %bb.4(0x80000000)
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- ; CHECK-NEXT: renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- ; CHECK-NEXT: B %bb.4
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.4.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- ; CHECK-NEXT: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- ; CHECK-NEXT: early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: bb.5.return:
- ; CHECK-NEXT: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: CFI_INSTRUCTION def_cfa $wsp, 0
- ; CHECK-NEXT: CFI_INSTRUCTION negate_ra_sign_state
- ; CHECK-NEXT: CFI_INSTRUCTION same_value $w18
- ; CHECK-NEXT: CFI_INSTRUCTION same_value $w30
- ; CHECK-NEXT: RET undef $lr, implicit killed $w0
- bb.0.entry:
- successors: %bb.5(0x30000000), %bb.1(0x50000000)
- liveins: $w0, $lr, $x18
-
- CBZW renamable $w0, %bb.5
-
- bb.1.if.end:
- successors: %bb.3(0x30000000), %bb.2(0x50000000)
- liveins: $w0, $lr, $x18
-
- early-clobber $x18 = frame-setup STRXpost $lr, $x18, 8
- frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
- frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
- frame-setup CFI_INSTRUCTION negate_ra_sign_state
- early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
- frame-setup CFI_INSTRUCTION def_cfa_offset 16
- frame-setup CFI_INSTRUCTION offset $w30, -16
- TBNZW renamable $w0, 31, %bb.3
-
- bb.2.if.else:
- successors: %bb.4(0x80000000)
- liveins: $w0
-
- renamable $w0 = nuw nsw ADDWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w8 = MOVZWi 1, 0
- $w0 = SUBWrs killed renamable $w8, killed renamable $w0, 0
- B %bb.4
-
- bb.3.if.then2:
- successors: %bb.4(0x80000000)
- liveins: $w0
-
- renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
- BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
- renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0
- B %bb.4
-
- bb.4.return:
- liveins: $w0
-
- early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
- frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp
- early-clobber $x18, $lr = frame-destroy LDRXpre $x18, -8
- RET undef $lr, implicit killed $w0
-
- bb.5.return:
- liveins: $w0
- RET undef $lr, implicit killed $w0
-
-...
; CHECK-NEXT: bl _bar
; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
; CHECK-NEXT: LBB4_2: ; %common.ret
-; CHECK-NEXT: .cfi_def_cfa wsp, 0
-; CHECK-NEXT: .cfi_same_value w30
-; CHECK-NEXT: .cfi_same_value w29
; CHECK-NEXT: ret
bb1:
%0 = icmp eq i32 %a, 0
; CHECK-NEXT: bl _bar
; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
; CHECK-NEXT: LBB5_2: ; %common.ret
-; CHECK-NEXT: .cfi_def_cfa wsp, 0
-; CHECK-NEXT: .cfi_same_value w30
-; CHECK-NEXT: .cfi_same_value w29
; CHECK-NEXT: ret
bb1:
%0 = icmp ne i32 %a, 0
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s
-define void @foo(i32 %i) uwtable {
-; CHECK-LABEL: foo:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT: .cfi_def_cfa_offset 16
-; CHECK-NEXT: .cfi_offset w30, -16
-; CHECK-NEXT: cmp w0, #7
-; CHECK-NEXT: b.eq .LBB0_3
-; CHECK-NEXT: // %bb.1: // %entry
-; CHECK-NEXT: cmp w0, #5
-; CHECK-NEXT: b.ne .LBB0_4
-; CHECK-NEXT: // %bb.2: // %if.then
-; CHECK-NEXT: bl bar
-; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
-; CHECK-NEXT: b bar
-; CHECK-NEXT: .LBB0_3: // %if.then2
-; CHECK-NEXT: bl bar
-; CHECK-NEXT: .LBB0_4: // %if.end3
-; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
-; CHECK-NEXT: b bar
+define void @foo(i32 %i) {
entry:
switch i32 %i, label %if.end3 [
i32 5, label %if.then
declare void @bar()
attributes #0 = { nomerge }
+
+; CHECK-LABEL: foo:
+; CHECK: // %bb.0: // %entry
+; CHECK: // %bb.1: // %entry
+; CHECK: // %bb.2: // %if.then
+; CHECK-NEXT: bl bar
+; CHECK: b bar
+; CHECK: .LBB0_3: // %if.then2
+; CHECK-NEXT: bl bar
+; CHECK: .LBB0_4: // %if.end3
+; CHECK: b bar
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: cbz w0, .LBB0_5
; CHECK-NEXT: .LBB0_3: // %common.ret.sink.split
-; CHECK-NEXT: .cfi_def_cfa wsp, 0
-; CHECK-NEXT: .cfi_same_value w30
; CHECK-NEXT: b extfunc
; CHECK-NEXT: .LBB0_4: // %b2
; CHECK-NEXT: bl extfunc
; CHECK-NEXT: ldp x28, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldp x29, x30, [sp], #32 // 16-byte Folded Reload
; CHECK-NEXT: .LBB0_2: // %if.end
-; CHECK-NEXT: .cfi_def_cfa wsp, 0
-; CHECK-NEXT: .cfi_same_value b8
-; CHECK-NEXT: .cfi_same_value b9
-; CHECK-NEXT: .cfi_same_value b10
-; CHECK-NEXT: .cfi_same_value b11
-; CHECK-NEXT: .cfi_same_value b12
-; CHECK-NEXT: .cfi_same_value b13
-; CHECK-NEXT: .cfi_same_value b14
-; CHECK-NEXT: .cfi_same_value b15
-; CHECK-NEXT: .cfi_same_value w19
-; CHECK-NEXT: .cfi_same_value w28
-; CHECK-NEXT: .cfi_same_value w30
-; CHECK-NEXT: .cfi_same_value w29
; CHECK-NEXT: ret
entry:
br i1 %cond, label %if.then, label %if.end