[llvm] 1e9a296 - [Xtensa] Implement branch analysis. (#110959)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 01:59:40 PDT 2024
Author: Andrei Safronov
Date: 2024-10-22T11:59:37+03:00
New Revision: 1e9a296557adbb5168346774c92814497e34524c
URL: https://github.com/llvm/llvm-project/commit/1e9a296557adbb5168346774c92814497e34524c
DIFF: https://github.com/llvm/llvm-project/commit/1e9a296557adbb5168346774c92814497e34524c.diff
LOG: [Xtensa] Implement branch analysis. (#110959)
Added:
llvm/test/CodeGen/Xtensa/branch_analyze.ll
Modified:
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
llvm/lib/Target/Xtensa/XtensaInstrInfo.h
llvm/lib/Target/Xtensa/XtensaInstrInfo.td
llvm/test/CodeGen/Xtensa/brcc.ll
llvm/test/CodeGen/Xtensa/ctlz-cttz-ctpop.ll
llvm/test/CodeGen/Xtensa/select-cc.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index 2263aadcb0dd3f..b2b4376ca040b6 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -185,3 +185,298 @@ void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,
report_fatal_error("Unsupported load immediate value");
}
}
+
+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!");
+ }
+}
+
+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;
+}
+
+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..9f45cf7c29ada7 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.h
@@ -74,6 +74,37 @@ class XtensaInstrInfo : public XtensaGenInstrInfo {
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned *Reg, int64_t Value) const;
+ bool
+ reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 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;
+
+ unsigned insertBranchAtInst(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock *TBB,
+ ArrayRef<MachineOperand> Cond, const 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/test/CodeGen/Xtensa/branch_analyze.ll b/llvm/test/CodeGen/Xtensa/branch_analyze.ll
new file mode 100644
index 00000000000000..3c0bcc54521821
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/branch_analyze.ll
@@ -0,0 +1,871 @@
+; 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
+
+declare void @foo() noreturn
+
+; Check reverseBranchCondition and analyzeBranch functions
+
+define i32 @eq(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: eq:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: beq a2, a8, .LBB0_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB0_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI0_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp eq i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @eq_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: eq_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bne a2, a8, .LBB1_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB1_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI1_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp eq i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: ne:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bne a2, a8, .LBB2_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB2_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI2_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp ne i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: ne_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: beq a2, a8, .LBB3_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB3_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI3_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp ne i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ult(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: ult:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bltu a2, a8, .LBB4_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB4_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI4_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ult_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: ult_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bgeu a2, a8, .LBB5_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB5_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI5_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @uge(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: uge:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bgeu a2, a8, .LBB6_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB6_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI6_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp uge i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @uge_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: uge_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bltu a2, a8, .LBB7_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB7_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI7_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp uge i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @slt(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: slt:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a2, a8, .LBB8_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB8_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI8_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @slt_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: slt_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a2, a8, .LBB9_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB9_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI9_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sle(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sle:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a8, a2, .LBB10_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB10_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI10_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sle i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sle_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sle_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a8, a2, .LBB11_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB11_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI11_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sle i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sgt(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sgt:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a8, a2, .LBB12_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB12_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI12_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sgt i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sgt_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sgt_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a8, a2, .LBB13_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB13_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI13_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sgt i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sge(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sge:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: bge a2, a8, .LBB14_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB14_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI14_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sge i32 %a, %b
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sge_reverse(i32 %a, ptr %bptr) {
+; XTENSA-LABEL: sge_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: l32i a8, a3, 0
+; XTENSA-NEXT: blt a2, a8, .LBB15_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB15_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI15_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %b = load i32, ptr %bptr
+ %cmp = icmp sge i32 %a, %b
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+; Check some cases of comparing operand with constant.
+
+define i32 @eq_zero(ptr %aptr) {
+; XTENSA-LABEL: eq_zero:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: beqz a8, .LBB16_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB16_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI16_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp eq i32 %a, 0
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @eq_zero_reverse(ptr %aptr) {
+; XTENSA-LABEL: eq_zero_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: bnez a8, .LBB17_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB17_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI17_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp eq i32 %a, 0
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne_zero(ptr %aptr) {
+; XTENSA-LABEL: ne_zero:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: bnez a8, .LBB18_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB18_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI18_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp ne i32 %a, 0
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne_zero_reverse(ptr %aptr) {
+; XTENSA-LABEL: ne_zero_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: beqz a8, .LBB19_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB19_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI19_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp ne i32 %a, 0
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @slt_zero(ptr %aptr) {
+; XTENSA-LABEL: slt_zero:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: bgez a8, .LBB20_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB20_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI20_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp slt i32 %a, 0
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @eq_imm(i32 %a) {
+; XTENSA-LABEL: eq_imm:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: beqi a2, 1, .LBB21_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB21_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI21_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp eq i32 %a, 1
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @eq_imm_reverse(i32 %a) {
+; XTENSA-LABEL: eq_imm_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: bnei a2, 1, .LBB22_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB22_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI22_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp eq i32 %a, 1
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne_imm(i32 %a) {
+; XTENSA-LABEL: ne_imm:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: beqi a2, 1, .LBB23_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB23_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI23_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp eq i32 %a, 1
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @ne_imm_reverse(i32 %a) {
+; XTENSA-LABEL: ne_imm_reverse:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: bnei a2, 1, .LBB24_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB24_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI24_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp eq i32 %a, 1
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @slt_imm(i32 %a) {
+; XTENSA-LABEL: slt_imm:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: bgei a2, -1, .LBB25_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB25_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI25_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp slt i32 %a, -1
+ br i1 %cmp, label %return, label %callit
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @sge_imm(i32 %a) {
+; XTENSA-LABEL: sge_imm:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: beqz a2, .LBB26_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB26_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI26_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %cmp = icmp ult i32 %a, 1
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
+
+define i32 @uge_imm(ptr %aptr) {
+; XTENSA-LABEL: uge_imm:
+; XTENSA: addi a8, a1, -16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: .cfi_def_cfa_offset 16
+; XTENSA-NEXT: s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT: .cfi_offset a0, -4
+; XTENSA-NEXT: memw
+; XTENSA-NEXT: l32i a8, a2, 0
+; XTENSA-NEXT: bgeui a8, 2, .LBB27_2
+; XTENSA-NEXT: # %bb.1: # %return
+; XTENSA-NEXT: movi a2, 1
+; XTENSA-NEXT: l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT: addi a8, a1, 16
+; XTENSA-NEXT: or a1, a8, a8
+; XTENSA-NEXT: ret
+; XTENSA-NEXT: .LBB27_2: # %callit
+; XTENSA-NEXT: l32r a8, .LCPI27_0
+; XTENSA-NEXT: callx0 a8
+entry:
+ %a = load volatile i32, ptr %aptr
+ %cmp = icmp uge i32 %a, 2
+ br i1 %cmp, label %callit, label %return
+
+callit:
+ call void @foo()
+ unreachable
+
+return:
+ ret i32 1
+}
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..bad57d58b28a67 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_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,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_1:
+; 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_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
; 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_1:
+; 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
More information about the llvm-commits
mailing list