Revert "[CodeGen] Async unwind - add a pass to fix CFI information"

This reverts commit 980c3e6dd2.

This commit had failing tests with clang crashing across various
AArch64/Linux buildots.

https://lab.llvm.org/buildbot/#/builders/179/builds/3346

Differential Revision: https://reviews.llvm.org/D114545
This commit is contained in:
Muhammad Omair Javaid 2022-04-05 13:09:42 +05:00
parent 64f659bee6
commit 0320115c16
27 changed files with 15 additions and 959 deletions

View File

@ -1,38 +0,0 @@
//===-- 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

View File

@ -494,9 +494,6 @@ namespace llvm {
// 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();

View File

@ -223,14 +223,6 @@ public:
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 {}

View File

@ -103,7 +103,6 @@ void initializeCFGSimplifyPassPass(PassRegistry&);
void initializeCFGuardPass(PassRegistry&);
void initializeCFGuardLongjmpPass(PassRegistry&);
void initializeCFGViewerLegacyPassPass(PassRegistry&);
void initializeCFIFixupPass(PassRegistry&);
void initializeCFIInstrInserterPass(PassRegistry&);
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);

View File

@ -257,8 +257,6 @@ public:
Options.SupportsDebugEntryValues = Enable;
}
void setCFIFixup(bool Enable) { Options.EnableCFIFixup = Enable; }
bool getAIXExtendedAltivecABI() const {
return Options.EnableAIXExtendedAltivecABI;
}

View File

@ -144,7 +144,6 @@ namespace llvm {
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
@ -357,9 +356,6 @@ namespace llvm {
/// 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.

View File

@ -273,12 +273,6 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
case MCCFIInstruction::OpUndefined:
OutStreamer->emitCFIUndefined(Inst.getRegister());
break;
case MCCFIInstruction::OpRememberState:
OutStreamer->emitCFIRememberState();
break;
case MCCFIInstruction::OpRestoreState:
OutStreamer->emitCFIRestoreState();
break;
}
}

View File

@ -1,215 +0,0 @@
//===------ 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;
}

View File

@ -38,7 +38,6 @@ add_llvm_component_library(LLVMCodeGen
CalcSpillWeights.cpp
CallingConvLower.cpp
CFGuardLongjmp.cpp
CFIFixup.cpp
CFIInstrInserter.cpp
CodeGen.cpp
CodeGenCommonISel.cpp

View File

@ -24,7 +24,6 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeBranchFolderPassPass(Registry);
initializeBranchRelaxationPass(Registry);
initializeCFGuardLongjmpPass(Registry);
initializeCFIFixupPass(Registry);
initializeCFIInstrInserterPass(Registry);
initializeCheckDebugMachineModulePass(Registry);
initializeCodeGenPreparePass(Registry);

View File

@ -383,9 +383,8 @@ void TailDuplicator::duplicateInstruction(
// 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);

View File

@ -21,8 +21,6 @@
#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"
@ -38,11 +36,6 @@ bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const
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

View File

@ -138,11 +138,6 @@ static cl::opt<RunOutliner> EnableMachineOutliner(
"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.
@ -1280,9 +1275,6 @@ void TargetPassConfig::addMachinePasses() {
addPass(createMachineFunctionSplitterPass());
}
if (!DisableCFIFixup && TM->Options.EnableCFIFixup)
addPass(createCFIFixup());
// Add passes that directly emit MI after all other MI passes.
addPreEmitPass2();

View File

@ -73,7 +73,6 @@ void initializeAArch64A53Fix835769Pass(PassRegistry&);
void initializeAArch64A57FPLoadBalancingPass(PassRegistry&);
void initializeAArch64AdvSIMDScalarPass(PassRegistry&);
void initializeAArch64BranchTargetsPass(PassRegistry&);
void initializeAArch64CFIFixupPass(PassRegistry&);
void initializeAArch64CollectLOHPass(PassRegistry&);
void initializeAArch64CondBrTuningPass(PassRegistry &);
void initializeAArch64CompressJumpTablesPass(PassRegistry&);

View File

@ -298,7 +298,6 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF,
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.
@ -581,57 +580,6 @@ void AArch64FrameLowering::emitCalleeSavedFrameMoves(
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

View File

@ -29,8 +29,6 @@ public:
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;

View File

@ -21,7 +21,6 @@
#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"
@ -356,10 +355,6 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
// AArch64 supports the debug entry values.
setSupportsDebugEntryValues(true);
// AArch64 supports fixing up the DWARF unwind information.
if (!getMCAsmInfo()->usesWindowsCFI())
setCFIFixup(true);
}
AArch64TargetMachine::~AArch64TargetMachine() = default;

View File

@ -67,7 +67,6 @@
; 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

View File

@ -208,7 +208,6 @@
; 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

View File

@ -276,7 +276,7 @@ define dso_local i1 @test_setcc3() {
}
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

View File

@ -34,10 +34,6 @@
; 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'
@ -59,10 +55,6 @@
; 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'

View File

@ -26,9 +26,6 @@ define i32 @foo(i32 %a, i32 %b) {
; 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:
@ -99,11 +96,6 @@ define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) {
; 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
;
@ -264,11 +256,6 @@ define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) {
; 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
;
@ -363,11 +350,6 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind uwtable {
; 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
;
@ -473,7 +455,6 @@ define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind uwtable {
; 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
;
@ -565,9 +546,6 @@ define i32 @inlineAsm(i32 %cond, i32 %N) {
; 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
;
@ -639,9 +617,6 @@ define i32 @callVariadicFunc(i32 %cond, i32 %N) {
; 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
;

View File

@ -1,524 +0,0 @@
# 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
...

View File

@ -153,9 +153,6 @@ define i64 @test_or_unpredictable(i32 %a, i32 %b) {
; 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
@ -189,9 +186,6 @@ define i64 @test_and_unpredictable(i32 %a, i32 %b) {
; 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

View File

@ -1,26 +1,6 @@
; 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
@ -43,3 +23,14 @@ if.end3:
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

View File

@ -26,8 +26,6 @@ define void @func() {
; 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

View File

@ -99,19 +99,6 @@ define void @foo(<vscale x 4 x i64> %dst, i1 %cond) {
; 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