[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