diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp index 2263aadcb0dd3..b2b4376ca040b 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 &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 &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 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 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 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 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 &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 8bf3f0618f285..9f45cf7c29ada 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 &Cond) const override; + + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify) const override; + + unsigned removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; + + unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, ArrayRef Cond, + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; + + unsigned insertBranchAtInst(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + MachineBasicBlock *TBB, + ArrayRef 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 &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 9773480624e92..e21de0448aa5a 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 0000000000000..3c0bcc5452182 --- /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 8bbc39c536c56..6d542f637cf65 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 f58bed19d4ee7..bad57d58b28a6 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 812e6a5b852ea..c86aa9f33ca36 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