[llvm] [Xtensa] Implement branch relaxation. (PR #110959)
Andrei Safronov via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 16:53:21 PDT 2024
https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/110959
>From 2b1a8b11349bc1ff82bcc61a987fe81cd0278f3c Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 3 Oct 2024 09:14:38 +0300
Subject: [PATCH 1/2] [Xtensa] Implement branch analysis.
---
llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp | 3 +
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 478 ++++++++++++++++++
llvm/lib/Target/Xtensa/XtensaInstrInfo.h | 48 ++
llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 2 +
llvm/lib/Target/Xtensa/XtensaRegisterInfo.h | 4 +
.../lib/Target/Xtensa/XtensaTargetMachine.cpp | 3 +
llvm/test/CodeGen/Xtensa/branch-relaxation.ll | 42 ++
llvm/test/CodeGen/Xtensa/branch.ll | 139 +++++
llvm/test/CodeGen/Xtensa/brcc.ll | 61 +--
llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll | 28 +-
llvm/test/CodeGen/Xtensa/select-cc.ll | 9 +-
11 files changed, 757 insertions(+), 60 deletions(-)
create mode 100644 llvm/test/CodeGen/Xtensa/branch-relaxation.ll
create mode 100644 llvm/test/CodeGen/Xtensa/branch.ll
diff --git a/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp b/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
index db86637ecf83f3..95dfafc13f3908 100644
--- a/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
@@ -69,6 +69,9 @@ void XtensaAsmPrinter::emitMachineConstantPoolValue(
const BlockAddress *BA =
cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();
MCSym = GetBlockAddressSymbol(BA);
+ } else if (ACPV->isMachineBasicBlock()) {
+ const MachineBasicBlock *MBB = cast<XtensaConstantPoolMBB>(ACPV)->getMBB();
+ MCSym = MBB->getSymbol();
} else if (ACPV->isJumpTable()) {
unsigned Idx = cast<XtensaConstantPoolJumpTable>(ACPV)->getIndex();
MCSym = this->GetJTISymbol(Idx, false);
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index 2263aadcb0dd3f..c944ea52533fcb 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -13,11 +13,13 @@
//===----------------------------------------------------------------------===//
#include "XtensaInstrInfo.h"
+#include "XtensaConstantPoolValue.h"
#include "XtensaTargetMachine.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
#define GET_INSTRINFO_CTOR_DTOR
#include "XtensaGenInstrInfo.inc"
@@ -185,3 +187,479 @@ void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,
report_fatal_error("Unsupported load immediate value");
}
}
+
+unsigned XtensaInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
+ const MachineFunction *MF = MI.getParent()->getParent();
+ const char *AsmStr = MI.getOperand(0).getSymbolName();
+ return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
+ }
+ default:
+ return MI.getDesc().getSize();
+ }
+}
+
+bool XtensaInstrInfo::reverseBranchCondition(
+ SmallVectorImpl<MachineOperand> &Cond) const {
+ assert(Cond.size() <= 4 && "Invalid branch condition!");
+
+ switch (Cond[0].getImm()) {
+ case Xtensa::BEQ:
+ Cond[0].setImm(Xtensa::BNE);
+ return false;
+ case Xtensa::BNE:
+ Cond[0].setImm(Xtensa::BEQ);
+ return false;
+ case Xtensa::BLT:
+ Cond[0].setImm(Xtensa::BGE);
+ return false;
+ case Xtensa::BGE:
+ Cond[0].setImm(Xtensa::BLT);
+ return false;
+ case Xtensa::BLTU:
+ Cond[0].setImm(Xtensa::BGEU);
+ return false;
+ case Xtensa::BGEU:
+ Cond[0].setImm(Xtensa::BLTU);
+ return false;
+
+ case Xtensa::BEQI:
+ Cond[0].setImm(Xtensa::BNEI);
+ return false;
+ case Xtensa::BNEI:
+ Cond[0].setImm(Xtensa::BEQI);
+ return false;
+ case Xtensa::BGEI:
+ Cond[0].setImm(Xtensa::BLTI);
+ return false;
+ case Xtensa::BLTI:
+ Cond[0].setImm(Xtensa::BGEI);
+ return false;
+ case Xtensa::BGEUI:
+ Cond[0].setImm(Xtensa::BLTUI);
+ return false;
+ case Xtensa::BLTUI:
+ Cond[0].setImm(Xtensa::BGEUI);
+ return false;
+
+ case Xtensa::BEQZ:
+ Cond[0].setImm(Xtensa::BNEZ);
+ return false;
+ case Xtensa::BNEZ:
+ Cond[0].setImm(Xtensa::BEQZ);
+ return false;
+ case Xtensa::BLTZ:
+ Cond[0].setImm(Xtensa::BGEZ);
+ return false;
+ case Xtensa::BGEZ:
+ Cond[0].setImm(Xtensa::BLTZ);
+ return false;
+
+ default:
+ report_fatal_error("Invalid branch condition!");
+ }
+}
+
+MachineBasicBlock *
+XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
+ unsigned OpCode = MI.getOpcode();
+ switch (OpCode) {
+ case Xtensa::BR_JT:
+ case Xtensa::JX:
+ return nullptr;
+ case Xtensa::J:
+ return MI.getOperand(0).getMBB();
+ case Xtensa::BEQ:
+ case Xtensa::BNE:
+ case Xtensa::BLT:
+ case Xtensa::BLTU:
+ case Xtensa::BGE:
+ case Xtensa::BGEU:
+ return MI.getOperand(2).getMBB();
+
+ case Xtensa::BEQI:
+ case Xtensa::BNEI:
+ case Xtensa::BLTI:
+ case Xtensa::BLTUI:
+ case Xtensa::BGEI:
+ case Xtensa::BGEUI:
+ return MI.getOperand(2).getMBB();
+
+ case Xtensa::BEQZ:
+ case Xtensa::BNEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BGEZ:
+ return MI.getOperand(1).getMBB();
+
+ default:
+ llvm_unreachable("Unknown branch opcode");
+ }
+}
+
+bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
+ int64_t BrOffset) const {
+ switch (BranchOp) {
+ case Xtensa::J:
+ BrOffset -= 4;
+ return isIntN(18, BrOffset);
+ case Xtensa::JX:
+ return true;
+ case Xtensa::BR_JT:
+ return true;
+ case Xtensa::BEQ:
+ case Xtensa::BNE:
+ case Xtensa::BLT:
+ case Xtensa::BLTU:
+ case Xtensa::BGE:
+ case Xtensa::BGEU:
+ case Xtensa::BEQI:
+ case Xtensa::BNEI:
+ case Xtensa::BLTI:
+ case Xtensa::BLTUI:
+ case Xtensa::BGEI:
+ case Xtensa::BGEUI:
+ BrOffset -= 4;
+ return isIntN(8, BrOffset);
+ case Xtensa::BEQZ:
+ case Xtensa::BNEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BGEZ:
+ BrOffset -= 4;
+ return isIntN(12, BrOffset);
+ default:
+ llvm_unreachable("Unknown branch opcode");
+ }
+}
+
+bool XtensaInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ SmallVectorImpl<MachineOperand> &Cond,
+ bool AllowModify = false) const {
+ // Most of the code and comments here are boilerplate.
+
+ // Start from the bottom of the block and work up, examining the
+ // terminator instructions.
+ MachineBasicBlock::iterator I = MBB.end();
+ while (I != MBB.begin()) {
+ --I;
+ if (I->isDebugValue())
+ continue;
+
+ // Working from the bottom, when we see a non-terminator instruction, we're
+ // done.
+ if (!isUnpredicatedTerminator(*I))
+ break;
+
+ // A terminator that isn't a branch can't easily be handled by this
+ // analysis.
+ SmallVector<MachineOperand, 4> ThisCond;
+ ThisCond.push_back(MachineOperand::CreateImm(0));
+ const MachineOperand *ThisTarget;
+ if (!isBranch(I, ThisCond, ThisTarget))
+ return true;
+
+ // Can't handle indirect branches.
+ if (!ThisTarget->isMBB())
+ return true;
+
+ if (ThisCond[0].getImm() == Xtensa::J) {
+ // Handle unconditional branches.
+ if (!AllowModify) {
+ TBB = ThisTarget->getMBB();
+ continue;
+ }
+
+ // If the block has any instructions after a JMP, delete them.
+ while (std::next(I) != MBB.end())
+ std::next(I)->eraseFromParent();
+
+ Cond.clear();
+ FBB = 0;
+
+ // TBB is used to indicate the unconditinal destination.
+ TBB = ThisTarget->getMBB();
+ continue;
+ }
+
+ // Working from the bottom, handle the first conditional branch.
+ if (Cond.empty()) {
+ // FIXME: add X86-style branch swap
+ FBB = TBB;
+ TBB = ThisTarget->getMBB();
+ Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
+
+ // push remaining operands
+ for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
+ Cond.push_back(I->getOperand(i));
+
+ continue;
+ }
+
+ // Handle subsequent conditional branches.
+ assert(Cond.size() <= 4);
+ assert(TBB);
+
+ // Only handle the case where all conditional branches branch to the same
+ // destination.
+ if (TBB != ThisTarget->getMBB())
+ return true;
+
+ // If the conditions are the same, we can leave them alone.
+ unsigned OldCond = Cond[0].getImm();
+ if (OldCond == ThisCond[0].getImm())
+ continue;
+ }
+
+ return false;
+}
+
+unsigned XtensaInstrInfo::removeBranch(MachineBasicBlock &MBB,
+ int *BytesRemoved) const {
+ // Most of the code and comments here are boilerplate.
+ MachineBasicBlock::iterator I = MBB.end();
+ unsigned Count = 0;
+ if (BytesRemoved)
+ *BytesRemoved = 0;
+
+ while (I != MBB.begin()) {
+ --I;
+ SmallVector<MachineOperand, 4> Cond;
+ Cond.push_back(MachineOperand::CreateImm(0));
+ const MachineOperand *Target;
+ if (!isBranch(I, Cond, Target))
+ break;
+ if (!Target->isMBB())
+ break;
+ // Remove the branch.
+ if (BytesRemoved)
+ *BytesRemoved += getInstSizeInBytes(*I);
+ I->eraseFromParent();
+ I = MBB.end();
+ ++Count;
+ }
+ return Count;
+}
+
+unsigned XtensaInstrInfo::insertBranch(
+ MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
+ unsigned Count = 0;
+ if (BytesAdded)
+ *BytesAdded = 0;
+ if (FBB) {
+ // Need to build two branches then
+ // one to branch to TBB on Cond
+ // and a second one immediately after to unconditionally jump to FBB
+ Count = InsertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
+ auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
+ Count++;
+ if (BytesAdded)
+ *BytesAdded += getInstSizeInBytes(MI);
+ return Count;
+ }
+ // This function inserts the branch at the end of the MBB
+ Count += InsertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
+ return Count;
+}
+
+void XtensaInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock &DestBB,
+ MachineBasicBlock &RestoreBB,
+ const DebugLoc &DL, int64_t BrOffset,
+ RegScavenger *RS) const {
+ assert(RS && "RegScavenger required for long branching");
+ assert(MBB.empty() &&
+ "new block should be inserted for expanding unconditional branch");
+ assert(MBB.pred_size() == 1);
+
+ MachineFunction *MF = MBB.getParent();
+ MachineRegisterInfo &MRI = MF->getRegInfo();
+ MachineConstantPool *ConstantPool = MF->getConstantPool();
+
+ if (!isInt<32>(BrOffset))
+ report_fatal_error(
+ "Branch offsets outside of the signed 32-bit range not supported");
+ XtensaConstantPoolValue *C =
+ XtensaConstantPoolMBB::Create(MF->getFunction().getContext(), &DestBB, 0);
+ unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
+
+ // FIXME: A virtual register must be used initially, as the register
+ // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
+ // uses the same workaround).
+ Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
+ auto II = MBB.end();
+
+ MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg)
+ .addConstantPoolIndex(Idx);
+ BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
+ RS->enterBasicBlockEnd(MBB);
+ unsigned Scav = RS->scavengeRegisterBackwards(Xtensa::ARRegClass,
+ L32R.getIterator(), false, 0);
+ MRI.replaceRegWith(ScratchReg, Scav);
+ MRI.clearVirtRegs();
+ RS->setRegUsed(Scav);
+}
+
+unsigned XtensaInstrInfo::InsertConstBranchAtInst(
+ MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
+ ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
+ // Shouldn't be a fall through.
+ assert(&MBB && "InsertBranch must not be told to insert a fallthrough");
+ assert(Cond.size() <= 4 &&
+ "Xtensa branch conditions have less than four components!");
+
+ if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
+ // Unconditional branch
+ MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
+ if (BytesAdded && MI)
+ *BytesAdded += getInstSizeInBytes(*MI);
+ return 1;
+ }
+
+ unsigned Count = 0;
+ unsigned BR_C = Cond[0].getImm();
+ MachineInstr *MI = nullptr;
+ switch (BR_C) {
+ case Xtensa::BEQ:
+ case Xtensa::BNE:
+ case Xtensa::BLT:
+ case Xtensa::BLTU:
+ case Xtensa::BGE:
+ case Xtensa::BGEU:
+ MI = BuildMI(MBB, I, DL, get(BR_C))
+ .addImm(offset)
+ .addReg(Cond[1].getReg())
+ .addReg(Cond[2].getReg());
+ break;
+ case Xtensa::BEQI:
+ case Xtensa::BNEI:
+ case Xtensa::BLTI:
+ case Xtensa::BLTUI:
+ case Xtensa::BGEI:
+ case Xtensa::BGEUI:
+ MI = BuildMI(MBB, I, DL, get(BR_C))
+ .addImm(offset)
+ .addReg(Cond[1].getReg())
+ .addImm(Cond[2].getImm());
+ break;
+ case Xtensa::BEQZ:
+ case Xtensa::BNEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BGEZ:
+ MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
+ break;
+ default:
+ llvm_unreachable("Invalid branch type!");
+ }
+ if (BytesAdded && MI)
+ *BytesAdded += getInstSizeInBytes(*MI);
+ ++Count;
+ return Count;
+}
+
+unsigned XtensaInstrInfo::InsertBranchAtInst(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock *TBB,
+ ArrayRef<MachineOperand> Cond,
+ const DebugLoc &DL,
+ int *BytesAdded) const {
+ // Shouldn't be a fall through.
+ assert(TBB && "InsertBranch must not be told to insert a fallthrough");
+ assert(Cond.size() <= 4 &&
+ "Xtensa branch conditions have less than four components!");
+
+ if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
+ // Unconditional branch
+ MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
+ if (BytesAdded && MI)
+ *BytesAdded += getInstSizeInBytes(*MI);
+ return 1;
+ }
+
+ unsigned Count = 0;
+ unsigned BR_C = Cond[0].getImm();
+ MachineInstr *MI = nullptr;
+ switch (BR_C) {
+ case Xtensa::BEQ:
+ case Xtensa::BNE:
+ case Xtensa::BLT:
+ case Xtensa::BLTU:
+ case Xtensa::BGE:
+ case Xtensa::BGEU:
+ MI = BuildMI(MBB, I, DL, get(BR_C))
+ .addReg(Cond[1].getReg())
+ .addReg(Cond[2].getReg())
+ .addMBB(TBB);
+ break;
+ case Xtensa::BEQI:
+ case Xtensa::BNEI:
+ case Xtensa::BLTI:
+ case Xtensa::BLTUI:
+ case Xtensa::BGEI:
+ case Xtensa::BGEUI:
+ MI = BuildMI(MBB, I, DL, get(BR_C))
+ .addReg(Cond[1].getReg())
+ .addImm(Cond[2].getImm())
+ .addMBB(TBB);
+ break;
+ case Xtensa::BEQZ:
+ case Xtensa::BNEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BGEZ:
+ MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
+ break;
+ default:
+ report_fatal_error("Invalid branch type!");
+ }
+ if (BytesAdded && MI)
+ *BytesAdded += getInstSizeInBytes(*MI);
+ ++Count;
+ return Count;
+}
+
+bool XtensaInstrInfo::isBranch(const MachineBasicBlock::iterator &MI,
+ SmallVectorImpl<MachineOperand> &Cond,
+ const MachineOperand *&Target) const {
+ unsigned OpCode = MI->getOpcode();
+ switch (OpCode) {
+ case Xtensa::J:
+ case Xtensa::JX:
+ case Xtensa::BR_JT:
+ Cond[0].setImm(OpCode);
+ Target = &MI->getOperand(0);
+ return true;
+ case Xtensa::BEQ:
+ case Xtensa::BNE:
+ case Xtensa::BLT:
+ case Xtensa::BLTU:
+ case Xtensa::BGE:
+ case Xtensa::BGEU:
+ Cond[0].setImm(OpCode);
+ Target = &MI->getOperand(2);
+ return true;
+
+ case Xtensa::BEQI:
+ case Xtensa::BNEI:
+ case Xtensa::BLTI:
+ case Xtensa::BLTUI:
+ case Xtensa::BGEI:
+ case Xtensa::BGEUI:
+ Cond[0].setImm(OpCode);
+ Target = &MI->getOperand(2);
+ return true;
+
+ case Xtensa::BEQZ:
+ case Xtensa::BNEZ:
+ case Xtensa::BLTZ:
+ case Xtensa::BGEZ:
+ Cond[0].setImm(OpCode);
+ Target = &MI->getOperand(1);
+ return true;
+
+ default:
+ assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
+ return false;
+ }
+}
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.h b/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
index 8bf3f0618f2857..ce9484a89751dd 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
@@ -38,6 +38,8 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
+ unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
+
// Return the XtensaRegisterInfo, which this class owns.
const XtensaRegisterInfo &getRegisterInfo() const { return RI; }
@@ -74,6 +76,52 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned *Reg, int64_t Value) const;
+ bool
+ reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
+
+ MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
+
+ bool isBranchOffsetInRange(unsigned BranchOpc,
+ int64_t BrOffset) const override;
+
+ bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ SmallVectorImpl<MachineOperand> &Cond,
+ bool AllowModify) const override;
+
+ unsigned removeBranch(MachineBasicBlock &MBB,
+ int *BytesRemoved = nullptr) const override;
+
+ unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
+ const DebugLoc &DL,
+ int *BytesAdded = nullptr) const override;
+
+ void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB,
+ MachineBasicBlock &RestoreBB, const DebugLoc &DL,
+ int64_t BrOffset = 0,
+ RegScavenger *RS = nullptr) const override;
+
+ unsigned InsertBranchAtInst(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock *TBB,
+ ArrayRef<MachineOperand> Cond, const DebugLoc &DL,
+ int *BytesAdded) const;
+
+ unsigned InsertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I,
+ int64_t offset,
+ ArrayRef<MachineOperand> Cond, DebugLoc DL,
+ int *BytesAdded) const;
+
+ // Return true if MI is a conditional or unconditional branch.
+ // When returning true, set Cond to the mask of condition-code
+ // values on which the instruction will branch, and set Target
+ // to the operand that contains the branch target. This target
+ // can be a register or a basic block.
+ bool isBranch(const MachineBasicBlock::iterator &MI,
+ SmallVectorImpl<MachineOperand> &Cond,
+ const MachineOperand *&Target) const;
+
const XtensaSubtarget &getSubtarget() const { return STI; }
};
} // end namespace llvm
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 9773480624e92e..e21de0448aa5ae 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -417,6 +417,8 @@ def BBSI : RRI8_Inst<0x07, (outs),
let imm8 = target;
}
+def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>;
+
//===----------------------------------------------------------------------===//
// Call and jump instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
index 8643ebb1c0f157..ede0eeb90b42de 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
@@ -38,6 +38,10 @@ class XtensaRegisterInfo : public XtensaGenRegisterInfo {
return true;
}
+ bool trackLivenessAfterRegAlloc(const MachineFunction &) const override {
+ return true;
+ }
+
const uint16_t *
getCalleeSavedRegs(const MachineFunction *MF = 0) const override;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
diff --git a/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp b/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
index 49c7faf84df1d3..0e60a3307e7c43 100644
--- a/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
@@ -95,6 +95,7 @@ class XtensaPassConfig : public TargetPassConfig {
}
bool addInstSelector() override;
+ void addPreEmitPass() override;
};
} // end anonymous namespace
@@ -103,6 +104,8 @@ bool XtensaPassConfig::addInstSelector() {
return false;
}
+void XtensaPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
+
TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
return new XtensaPassConfig(*this, PM);
}
diff --git a/llvm/test/CodeGen/Xtensa/branch-relaxation.ll b/llvm/test/CodeGen/Xtensa/branch-relaxation.ll
new file mode 100644
index 00000000000000..78470e4d3a6fbc
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/branch-relaxation.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA %s
+
+define i32 @jx(i1 %a) {
+; XTENSA-LABEL: jx:
+; XTENSA: movi a8, 1
+; XTENSA-NEXT: and a8, a2, a8
+; XTENSA-NEXT: bnez a8, .LBB0_1
+; XTENSA-NEXT: # %bb.3:
+; XTENSA-NEXT: l32r a8, .LCPI0_0
+; XTENSA-NEXT: jx a8
+; XTENSA-NEXT: .LBB0_1: # %iftrue
+; XTENSA-NEXT: #APP
+; XTENSA-NEXT: #NO_APP
+; XTENSA-NEXT: #APP
+; XTENSA-NEXT: .space 1048576
+; XTENSA-NEXT: #NO_APP
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB0_2: # %jmp
+; XTENSA-NEXT: #APP
+; XTENSA-NEXT: #NO_APP
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: ret
+ br i1 %a, label %iftrue, label %jmp
+
+jmp:
+ call void asm sideeffect "", ""()
+ br label %tail
+
+iftrue:
+ call void asm sideeffect "", ""()
+ br label %space
+
+space:
+ call void asm sideeffect ".space 1048576", ""()
+ br label %tail
+
+tail:
+ ret i32 1
+}
diff --git a/llvm/test/CodeGen/Xtensa/branch.ll b/llvm/test/CodeGen/Xtensa/branch.ll
new file mode 100644
index 00000000000000..a1f83478f4adb8
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/branch.ll
@@ -0,0 +1,139 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA %s
+
+define void @foo(i32 %a, ptr %b, i1 %c) nounwind {
+; XTENSA-LABEL: foo:
+; XTENSA: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: beq a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.1: # %test2
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bne a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.2: # %test3
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.3: # %test4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.4: # %test5
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bltu a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.5: # %test6
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bgeu a8, a2, .LBB0_14
+; XTENSA-NEXT: # %bb.6: # %test7
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a2, a8, .LBB0_14
+; XTENSA-NEXT: # %bb.7: # %test8
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a2, a8, .LBB0_14
+; XTENSA-NEXT: # %bb.8: # %test9
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bltu a2, a8, .LBB0_14
+; XTENSA-NEXT: # %bb.9: # %test10
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bgeu a2, a8, .LBB0_14
+; XTENSA-NEXT: # %bb.10: # %test11
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: movi a8, 1
+; XTENSA-NEXT: and a8, a4, a8
+; XTENSA-NEXT: bnez a8, .LBB0_14
+; XTENSA-NEXT: # %bb.11: # %test12
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: movi a9, -1
+; XTENSA-NEXT: blt a9, a8, .LBB0_14
+; XTENSA-NEXT: # %bb.12: # %test13
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blti a8, 1, .LBB0_14
+; XTENSA-NEXT: # %bb.13: # %test14
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: .LBB0_14: # %end
+; XTENSA-NEXT: ret
+ %val1 = load volatile i32, ptr %b
+ %tst1 = icmp eq i32 %val1, %a
+ br i1 %tst1, label %end, label %test2
+
+test2:
+ %val2 = load volatile i32, ptr %b
+ %tst2 = icmp ne i32 %val2, %a
+ br i1 %tst2, label %end, label %test3
+
+test3:
+ %val3 = load volatile i32, ptr %b
+ %tst3 = icmp slt i32 %val3, %a
+ br i1 %tst3, label %end, label %test4
+
+test4:
+ %val4 = load volatile i32, ptr %b
+ %tst4 = icmp sge i32 %val4, %a
+ br i1 %tst4, label %end, label %test5
+
+test5:
+ %val5 = load volatile i32, ptr %b
+ %tst5 = icmp ult i32 %val5, %a
+ br i1 %tst5, label %end, label %test6
+
+test6:
+ %val6 = load volatile i32, ptr %b
+ %tst6 = icmp uge i32 %val6, %a
+ br i1 %tst6, label %end, label %test7
+
+
+test7:
+ %val7 = load volatile i32, ptr %b
+ %tst7 = icmp sgt i32 %val7, %a
+ br i1 %tst7, label %end, label %test8
+
+test8:
+ %val8 = load volatile i32, ptr %b
+ %tst8 = icmp sle i32 %val8, %a
+ br i1 %tst8, label %end, label %test9
+
+test9:
+ %val9 = load volatile i32, ptr %b
+ %tst9 = icmp ugt i32 %val9, %a
+ br i1 %tst9, label %end, label %test10
+
+test10:
+ %val10 = load volatile i32, ptr %b
+ %tst10 = icmp ule i32 %val10, %a
+ br i1 %tst10, label %end, label %test11
+
+
+test11:
+ %val11 = load volatile i32, ptr %b
+ br i1 %c, label %end, label %test12
+
+
+test12:
+ %val12 = load volatile i32, ptr %b
+ %tst12 = icmp sgt i32 %val12, -1
+ br i1 %tst12, label %end, label %test13
+
+
+test13:
+ %val13 = load volatile i32, ptr %b
+ %tst13 = icmp slt i32 %val13, 1
+ br i1 %tst13, label %end, label %test14
+
+test14:
+ %val14 = load volatile i32, ptr %b
+ br label %end
+
+end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/Xtensa/brcc.ll b/llvm/test/CodeGen/Xtensa/brcc.ll
index 8bbc39c536c561..6d542f637cf659 100644
--- a/llvm/test/CodeGen/Xtensa/brcc.ll
+++ b/llvm/test/CodeGen/Xtensa/brcc.ll
@@ -1,16 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \
; RUN: | FileCheck %s
define i32 @brcc_sgt(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_sgt:
; CHECK: bge a3, a2, .LBB0_2
-; CHECK-NEXT: j .LBB0_1
-; CHECK-NEXT: .LBB0_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB0_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB0_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB0_3: # %exit
; CHECK-NEXT: ret
%wb = icmp sgt i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -28,13 +27,11 @@ exit:
define i32 @brcc_ugt(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_ugt:
; CHECK: bgeu a3, a2, .LBB1_2
-; CHECK-NEXT: j .LBB1_1
-; CHECK-NEXT: .LBB1_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB1_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB1_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB1_3: # %exit
; CHECK-NEXT: ret
%wb = icmp ugt i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -52,13 +49,11 @@ exit:
define i32 @brcc_sle(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_sle:
; CHECK: blt a3, a2, .LBB2_2
-; CHECK-NEXT: j .LBB2_1
-; CHECK-NEXT: .LBB2_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB2_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB2_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB2_3: # %exit
; CHECK-NEXT: ret
%wb = icmp sle i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -76,13 +71,11 @@ exit:
define i32 @brcc_ule(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_ule:
; CHECK: bltu a3, a2, .LBB3_2
-; CHECK-NEXT: j .LBB3_1
-; CHECK-NEXT: .LBB3_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB3_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB3_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB3_3: # %exit
; CHECK-NEXT: ret
%wb = icmp ule i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -100,13 +93,11 @@ exit:
define i32 @brcc_eq(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_eq:
; CHECK: bne a2, a3, .LBB4_2
-; CHECK-NEXT: j .LBB4_1
-; CHECK-NEXT: .LBB4_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB4_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB4_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB4_3: # %exit
; CHECK-NEXT: ret
%wb = icmp eq i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -124,13 +115,11 @@ exit:
define i32 @brcc_ne(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_ne:
; CHECK: beq a2, a3, .LBB5_2
-; CHECK-NEXT: j .LBB5_1
-; CHECK-NEXT: .LBB5_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB5_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB5_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB5_3: # %exit
; CHECK-NEXT: ret
%wb = icmp ne i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -148,13 +137,11 @@ exit:
define i32 @brcc_ge(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_ge:
; CHECK: blt a2, a3, .LBB6_2
-; CHECK-NEXT: j .LBB6_1
-; CHECK-NEXT: .LBB6_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB6_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB6_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB6_3: # %exit
; CHECK-NEXT: ret
%wb = icmp sge i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -172,13 +159,11 @@ exit:
define i32 @brcc_lt(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_lt:
; CHECK: bge a2, a3, .LBB7_2
-; CHECK-NEXT: j .LBB7_1
-; CHECK-NEXT: .LBB7_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB7_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB7_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB7_3: # %exit
; CHECK-NEXT: ret
%wb = icmp slt i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -196,13 +181,11 @@ exit:
define i32 @brcc_uge(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_uge:
; CHECK: bltu a2, a3, .LBB8_2
-; CHECK-NEXT: j .LBB8_1
-; CHECK-NEXT: .LBB8_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB8_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB8_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB8_3: # %exit
; CHECK-NEXT: ret
%wb = icmp uge i32 %a, %b
br i1 %wb, label %t1, label %t2
@@ -220,13 +203,11 @@ exit:
define i32 @brcc_ult(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: brcc_ult:
; CHECK: bgeu a2, a3, .LBB9_2
-; CHECK-NEXT: j .LBB9_1
-; CHECK-NEXT: .LBB9_1: # %t1
+; CHECK-NEXT: # %bb.1: # %t1
; CHECK-NEXT: addi a2, a2, 4
-; CHECK-NEXT: j .LBB9_3
+; CHECK-NEXT: ret
; CHECK-NEXT: .LBB9_2: # %t2
; CHECK-NEXT: addi a2, a3, 8
-; CHECK-NEXT: .LBB9_3: # %exit
; CHECK-NEXT: ret
%wb = icmp ult i32 %a, %b
br i1 %wb, label %t1, label %t2
diff --git a/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
index f58bed19d4ee77..60303235386256 100644
--- a/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
+++ b/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
@@ -8,10 +8,8 @@ declare i32 @llvm.ctpop.i32(i32)
define i32 @test_cttz_i32(i32 %a) nounwind {
; XTENSA-LABEL: test_cttz_i32:
-; XTENSA: movi a8, 32
-; XTENSA-NEXT: beqz a2, .LBB0_2
-; XTENSA-NEXT: j .LBB0_1
-; XTENSA-NEXT: .LBB0_1: # %cond.false
+; XTENSA: beqz a2, .LBB0_2
+; XTENSA-NEXT: # %bb.1: # %cond.false
; XTENSA-NEXT: movi a8, -1
; XTENSA-NEXT: xor a8, a2, a8
; XTENSA-NEXT: addi a9, a2, -1
@@ -33,9 +31,10 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
; XTENSA-NEXT: add a8, a8, a9
; XTENSA-NEXT: slli a9, a8, 16
; XTENSA-NEXT: add a8, a8, a9
-; XTENSA-NEXT: extui a8, a8, 24, 8
-; XTENSA-NEXT: .LBB0_2: # %cond.end
-; XTENSA-NEXT: or a2, a8, a8
+; XTENSA-NEXT: extui a2, a8, 24, 8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB0_2:
+; XTENSA-NEXT: movi a2, 32
; XTENSA-NEXT: ret
%tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
ret i32 %tmp
@@ -72,13 +71,10 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
define i32 @test_ctlz_i32(i32 %a) nounwind {
; XTENSA-LABEL: test_ctlz_i32:
-; XTENSA: or a8, a2, a2
-; XTENSA-NEXT: movi a2, 32
-; XTENSA-NEXT: beqz a8, .LBB2_2
-; XTENSA-NEXT: j .LBB2_1
-; XTENSA-NEXT: .LBB2_1: # %cond.false
-; XTENSA-NEXT: srli a9, a8, 1
-; XTENSA-NEXT: or a8, a8, a9
+; XTENSA: beqz a2, .LBB2_2
+; XTENSA-NEXT: # %bb.1: # %cond.false
+; XTENSA-NEXT: srli a8, a2, 1
+; XTENSA-NEXT: or a8, a2, a8
; XTENSA-NEXT: srli a9, a8, 2
; XTENSA-NEXT: or a8, a8, a9
; XTENSA-NEXT: srli a9, a8, 4
@@ -107,7 +103,9 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
; XTENSA-NEXT: slli a9, a8, 16
; XTENSA-NEXT: add a8, a8, a9
; XTENSA-NEXT: extui a2, a8, 24, 8
-; XTENSA-NEXT: .LBB2_2: # %cond.end
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB2_2:
+; XTENSA-NEXT: movi a2, 32
; XTENSA-NEXT: ret
%tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
ret i32 %tmp
diff --git a/llvm/test/CodeGen/Xtensa/select-cc.ll b/llvm/test/CodeGen/Xtensa/select-cc.ll
index 812e6a5b852eab..c86aa9f33ca36b 100644
--- a/llvm/test/CodeGen/Xtensa/select-cc.ll
+++ b/llvm/test/CodeGen/Xtensa/select-cc.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=xtensa -disable-block-placement -verify-machineinstrs < %s \
; RUN: | FileCheck %s
@@ -161,12 +162,10 @@ define i32 @f_slt_imm(i32 %a, ptr %b) nounwind {
define i32 @f_sgt_imm(i32 %a, ptr %b) nounwind {
; CHECK-LABEL: f_sgt_imm:
-; CHECK: or a8, a2, a2
-; CHECK-NEXT: l32i a2, a3, 0
-; CHECK-NEXT: movi a9, -1
-; CHECK-NEXT: bge a9, a8, .LBB11_2
+; CHECK: movi a8, -1
+; CHECK-NEXT: blt a8, a2, .LBB11_2
; CHECK-NEXT: # %bb.1:
-; CHECK-NEXT: or a2, a8, a8
+; CHECK-NEXT: l32i a2, a3, 0
; CHECK-NEXT: .LBB11_2:
; CHECK-NEXT: ret
%val1 = load i32, ptr %b
>From 51518b90b015f8b2da3ceed9f156e3366a7e6188 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Fri, 11 Oct 2024 02:48:48 +0300
Subject: [PATCH 2/2] [PATCH] [Xtensa] Remove redundant code.
---
llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp | 3 -
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 180 ------------------
llvm/lib/Target/Xtensa/XtensaInstrInfo.h | 17 --
llvm/lib/Target/Xtensa/XtensaRegisterInfo.h | 4 -
.../lib/Target/Xtensa/XtensaTargetMachine.cpp | 3 -
llvm/test/CodeGen/Xtensa/branch-relaxation.ll | 42 ----
llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll | 12 +-
7 files changed, 6 insertions(+), 255 deletions(-)
delete mode 100644 llvm/test/CodeGen/Xtensa/branch-relaxation.ll
diff --git a/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp b/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
index 95dfafc13f3908..db86637ecf83f3 100644
--- a/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
@@ -69,9 +69,6 @@ void XtensaAsmPrinter::emitMachineConstantPoolValue(
const BlockAddress *BA =
cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();
MCSym = GetBlockAddressSymbol(BA);
- } else if (ACPV->isMachineBasicBlock()) {
- const MachineBasicBlock *MBB = cast<XtensaConstantPoolMBB>(ACPV)->getMBB();
- MCSym = MBB->getSymbol();
} else if (ACPV->isJumpTable()) {
unsigned Idx = cast<XtensaConstantPoolJumpTable>(ACPV)->getIndex();
MCSym = this->GetJTISymbol(Idx, false);
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index c944ea52533fcb..f7cfcbd03f229f 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -13,13 +13,11 @@
//===----------------------------------------------------------------------===//
#include "XtensaInstrInfo.h"
-#include "XtensaConstantPoolValue.h"
#include "XtensaTargetMachine.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
#define GET_INSTRINFO_CTOR_DTOR
#include "XtensaGenInstrInfo.inc"
@@ -188,18 +186,6 @@ void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,
}
}
-unsigned XtensaInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
- switch (MI.getOpcode()) {
- case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
- const MachineFunction *MF = MI.getParent()->getParent();
- const char *AsmStr = MI.getOperand(0).getSymbolName();
- return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
- }
- default:
- return MI.getDesc().getSize();
- }
-}
-
bool XtensaInstrInfo::reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() <= 4 && "Invalid branch condition!");
@@ -261,77 +247,6 @@ bool XtensaInstrInfo::reverseBranchCondition(
}
}
-MachineBasicBlock *
-XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
- unsigned OpCode = MI.getOpcode();
- switch (OpCode) {
- case Xtensa::BR_JT:
- case Xtensa::JX:
- return nullptr;
- case Xtensa::J:
- return MI.getOperand(0).getMBB();
- case Xtensa::BEQ:
- case Xtensa::BNE:
- case Xtensa::BLT:
- case Xtensa::BLTU:
- case Xtensa::BGE:
- case Xtensa::BGEU:
- return MI.getOperand(2).getMBB();
-
- case Xtensa::BEQI:
- case Xtensa::BNEI:
- case Xtensa::BLTI:
- case Xtensa::BLTUI:
- case Xtensa::BGEI:
- case Xtensa::BGEUI:
- return MI.getOperand(2).getMBB();
-
- case Xtensa::BEQZ:
- case Xtensa::BNEZ:
- case Xtensa::BLTZ:
- case Xtensa::BGEZ:
- return MI.getOperand(1).getMBB();
-
- default:
- llvm_unreachable("Unknown branch opcode");
- }
-}
-
-bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
- int64_t BrOffset) const {
- switch (BranchOp) {
- case Xtensa::J:
- BrOffset -= 4;
- return isIntN(18, BrOffset);
- case Xtensa::JX:
- return true;
- case Xtensa::BR_JT:
- return true;
- case Xtensa::BEQ:
- case Xtensa::BNE:
- case Xtensa::BLT:
- case Xtensa::BLTU:
- case Xtensa::BGE:
- case Xtensa::BGEU:
- case Xtensa::BEQI:
- case Xtensa::BNEI:
- case Xtensa::BLTI:
- case Xtensa::BLTUI:
- case Xtensa::BGEI:
- case Xtensa::BGEUI:
- BrOffset -= 4;
- return isIntN(8, BrOffset);
- case Xtensa::BEQZ:
- case Xtensa::BNEZ:
- case Xtensa::BLTZ:
- case Xtensa::BGEZ:
- BrOffset -= 4;
- return isIntN(12, BrOffset);
- default:
- llvm_unreachable("Unknown branch opcode");
- }
-}
-
bool XtensaInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
@@ -464,101 +379,6 @@ unsigned XtensaInstrInfo::insertBranch(
return Count;
}
-void XtensaInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
- MachineBasicBlock &DestBB,
- MachineBasicBlock &RestoreBB,
- const DebugLoc &DL, int64_t BrOffset,
- RegScavenger *RS) const {
- assert(RS && "RegScavenger required for long branching");
- assert(MBB.empty() &&
- "new block should be inserted for expanding unconditional branch");
- assert(MBB.pred_size() == 1);
-
- MachineFunction *MF = MBB.getParent();
- MachineRegisterInfo &MRI = MF->getRegInfo();
- MachineConstantPool *ConstantPool = MF->getConstantPool();
-
- if (!isInt<32>(BrOffset))
- report_fatal_error(
- "Branch offsets outside of the signed 32-bit range not supported");
- XtensaConstantPoolValue *C =
- XtensaConstantPoolMBB::Create(MF->getFunction().getContext(), &DestBB, 0);
- unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
-
- // FIXME: A virtual register must be used initially, as the register
- // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
- // uses the same workaround).
- Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
- auto II = MBB.end();
-
- MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg)
- .addConstantPoolIndex(Idx);
- BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
- RS->enterBasicBlockEnd(MBB);
- unsigned Scav = RS->scavengeRegisterBackwards(Xtensa::ARRegClass,
- L32R.getIterator(), false, 0);
- MRI.replaceRegWith(ScratchReg, Scav);
- MRI.clearVirtRegs();
- RS->setRegUsed(Scav);
-}
-
-unsigned XtensaInstrInfo::InsertConstBranchAtInst(
- MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
- ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
- // Shouldn't be a fall through.
- assert(&MBB && "InsertBranch must not be told to insert a fallthrough");
- assert(Cond.size() <= 4 &&
- "Xtensa branch conditions have less than four components!");
-
- if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
- // Unconditional branch
- MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
- if (BytesAdded && MI)
- *BytesAdded += getInstSizeInBytes(*MI);
- return 1;
- }
-
- unsigned Count = 0;
- unsigned BR_C = Cond[0].getImm();
- MachineInstr *MI = nullptr;
- switch (BR_C) {
- case Xtensa::BEQ:
- case Xtensa::BNE:
- case Xtensa::BLT:
- case Xtensa::BLTU:
- case Xtensa::BGE:
- case Xtensa::BGEU:
- MI = BuildMI(MBB, I, DL, get(BR_C))
- .addImm(offset)
- .addReg(Cond[1].getReg())
- .addReg(Cond[2].getReg());
- break;
- case Xtensa::BEQI:
- case Xtensa::BNEI:
- case Xtensa::BLTI:
- case Xtensa::BLTUI:
- case Xtensa::BGEI:
- case Xtensa::BGEUI:
- MI = BuildMI(MBB, I, DL, get(BR_C))
- .addImm(offset)
- .addReg(Cond[1].getReg())
- .addImm(Cond[2].getImm());
- break;
- case Xtensa::BEQZ:
- case Xtensa::BNEZ:
- case Xtensa::BLTZ:
- case Xtensa::BGEZ:
- MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
- break;
- default:
- llvm_unreachable("Invalid branch type!");
- }
- if (BytesAdded && MI)
- *BytesAdded += getInstSizeInBytes(*MI);
- ++Count;
- return Count;
-}
-
unsigned XtensaInstrInfo::InsertBranchAtInst(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
MachineBasicBlock *TBB,
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.h b/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
index ce9484a89751dd..6e00f49a95c823 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
@@ -38,8 +38,6 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
- unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
-
// Return the XtensaRegisterInfo, which this class owns.
const XtensaRegisterInfo &getRegisterInfo() const { return RI; }
@@ -79,11 +77,6 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
- MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
-
- bool isBranchOffsetInRange(unsigned BranchOpc,
- int64_t BrOffset) const override;
-
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
@@ -97,22 +90,12 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
- void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB,
- MachineBasicBlock &RestoreBB, const DebugLoc &DL,
- int64_t BrOffset = 0,
- RegScavenger *RS = nullptr) const override;
-
unsigned InsertBranchAtInst(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
MachineBasicBlock *TBB,
ArrayRef<MachineOperand> Cond, const DebugLoc &DL,
int *BytesAdded) const;
- unsigned InsertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I,
- int64_t offset,
- ArrayRef<MachineOperand> Cond, DebugLoc DL,
- int *BytesAdded) const;
-
// Return true if MI is a conditional or unconditional branch.
// When returning true, set Cond to the mask of condition-code
// values on which the instruction will branch, and set Target
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
index ede0eeb90b42de..8643ebb1c0f157 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
@@ -38,10 +38,6 @@ class XtensaRegisterInfo : public XtensaGenRegisterInfo {
return true;
}
- bool trackLivenessAfterRegAlloc(const MachineFunction &) const override {
- return true;
- }
-
const uint16_t *
getCalleeSavedRegs(const MachineFunction *MF = 0) const override;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
diff --git a/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp b/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
index 0e60a3307e7c43..49c7faf84df1d3 100644
--- a/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp
@@ -95,7 +95,6 @@ class XtensaPassConfig : public TargetPassConfig {
}
bool addInstSelector() override;
- void addPreEmitPass() override;
};
} // end anonymous namespace
@@ -104,8 +103,6 @@ bool XtensaPassConfig::addInstSelector() {
return false;
}
-void XtensaPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
-
TargetPassConfig *XtensaTargetMachine::createPassConfig(PassManagerBase &PM) {
return new XtensaPassConfig(*this, PM);
}
diff --git a/llvm/test/CodeGen/Xtensa/branch-relaxation.ll b/llvm/test/CodeGen/Xtensa/branch-relaxation.ll
deleted file mode 100644
index 78470e4d3a6fbc..00000000000000
--- a/llvm/test/CodeGen/Xtensa/branch-relaxation.ll
+++ /dev/null
@@ -1,42 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefix=XTENSA %s
-
-define i32 @jx(i1 %a) {
-; XTENSA-LABEL: jx:
-; XTENSA: movi a8, 1
-; XTENSA-NEXT: and a8, a2, a8
-; XTENSA-NEXT: bnez a8, .LBB0_1
-; XTENSA-NEXT: # %bb.3:
-; XTENSA-NEXT: l32r a8, .LCPI0_0
-; XTENSA-NEXT: jx a8
-; XTENSA-NEXT: .LBB0_1: # %iftrue
-; XTENSA-NEXT: #APP
-; XTENSA-NEXT: #NO_APP
-; XTENSA-NEXT: #APP
-; XTENSA-NEXT: .space 1048576
-; XTENSA-NEXT: #NO_APP
-; XTENSA-NEXT: movi a2, 1
-; XTENSA-NEXT: ret
-; XTENSA-NEXT: .LBB0_2: # %jmp
-; XTENSA-NEXT: #APP
-; XTENSA-NEXT: #NO_APP
-; XTENSA-NEXT: movi a2, 1
-; XTENSA-NEXT: ret
- br i1 %a, label %iftrue, label %jmp
-
-jmp:
- call void asm sideeffect "", ""()
- br label %tail
-
-iftrue:
- call void asm sideeffect "", ""()
- br label %space
-
-space:
- call void asm sideeffect ".space 1048576", ""()
- br label %tail
-
-tail:
- ret i32 1
-}
diff --git a/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
index 60303235386256..bad57d58b28a67 100644
--- a/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
+++ b/llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
@@ -8,8 +8,8 @@ declare i32 @llvm.ctpop.i32(i32)
define i32 @test_cttz_i32(i32 %a) nounwind {
; XTENSA-LABEL: test_cttz_i32:
-; XTENSA: beqz a2, .LBB0_2
-; XTENSA-NEXT: # %bb.1: # %cond.false
+; XTENSA: beqz a2, .LBB0_1
+; XTENSA-NEXT: # %bb.2: # %cond.false
; XTENSA-NEXT: movi a8, -1
; XTENSA-NEXT: xor a8, a2, a8
; XTENSA-NEXT: addi a9, a2, -1
@@ -33,7 +33,7 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
; XTENSA-NEXT: add a8, a8, a9
; XTENSA-NEXT: extui a2, a8, 24, 8
; XTENSA-NEXT: ret
-; XTENSA-NEXT: .LBB0_2:
+; XTENSA-NEXT: .LBB0_1:
; XTENSA-NEXT: movi a2, 32
; XTENSA-NEXT: ret
%tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
@@ -71,8 +71,8 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
define i32 @test_ctlz_i32(i32 %a) nounwind {
; XTENSA-LABEL: test_ctlz_i32:
-; XTENSA: beqz a2, .LBB2_2
-; XTENSA-NEXT: # %bb.1: # %cond.false
+; XTENSA: beqz a2, .LBB2_1
+; XTENSA-NEXT: # %bb.2: # %cond.false
; XTENSA-NEXT: srli a8, a2, 1
; XTENSA-NEXT: or a8, a2, a8
; XTENSA-NEXT: srli a9, a8, 2
@@ -104,7 +104,7 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
; XTENSA-NEXT: add a8, a8, a9
; XTENSA-NEXT: extui a2, a8, 24, 8
; XTENSA-NEXT: ret
-; XTENSA-NEXT: .LBB2_2:
+; XTENSA-NEXT: .LBB2_1:
; XTENSA-NEXT: movi a2, 32
; XTENSA-NEXT: ret
%tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
More information about the llvm-commits
mailing list