[llvm] r209134 - [ARM64] Split tbz/tbnz into W/X register variant

Bradley Smith bradley.smith at arm.com
Mon May 19 08:58:16 PDT 2014


Author: brasmi01
Date: Mon May 19 10:58:15 2014
New Revision: 209134

URL: http://llvm.org/viewvc/llvm-project?rev=209134&view=rev
Log:
[ARM64] Split tbz/tbnz into W/X register variant

Modified:
    llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp
    llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
    llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
    llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
    llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
    llvm/trunk/test/CodeGen/ARM64/early-ifcvt.ll

Modified: llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp Mon May 19 10:58:15 2014
@@ -275,8 +275,10 @@ static bool isConditionalBranch(unsigned
   switch (Opc) {
   default:
     return false;
-  case ARM64::TBZ:
-  case ARM64::TBNZ:
+  case ARM64::TBZW:
+  case ARM64::TBNZW:
+  case ARM64::TBZX:
+  case ARM64::TBNZX:
   case ARM64::CBZW:
   case ARM64::CBNZW:
   case ARM64::CBZX:
@@ -290,8 +292,10 @@ static MachineBasicBlock *getDestBlock(M
   switch (MI->getOpcode()) {
   default:
     assert(0 && "unexpected opcode!");
-  case ARM64::TBZ:
-  case ARM64::TBNZ:
+  case ARM64::TBZW:
+  case ARM64::TBNZW:
+  case ARM64::TBZX:
+  case ARM64::TBNZX:
     return MI->getOperand(2).getMBB();
   case ARM64::CBZW:
   case ARM64::CBNZW:
@@ -306,8 +310,10 @@ static unsigned getOppositeConditionOpco
   switch (Opc) {
   default:
     assert(0 && "unexpected opcode!");
-  case ARM64::TBNZ:    return ARM64::TBZ;
-  case ARM64::TBZ:     return ARM64::TBNZ;
+  case ARM64::TBNZW:   return ARM64::TBZW;
+  case ARM64::TBNZX:   return ARM64::TBZX;
+  case ARM64::TBZW:    return ARM64::TBNZW;
+  case ARM64::TBZX:    return ARM64::TBNZX;
   case ARM64::CBNZW:   return ARM64::CBZW;
   case ARM64::CBNZX:   return ARM64::CBZX;
   case ARM64::CBZW:    return ARM64::CBNZW;
@@ -320,8 +326,10 @@ static unsigned getBranchDisplacementBit
   switch (Opc) {
   default:
     assert(0 && "unexpected opcode!");
-  case ARM64::TBNZ:
-  case ARM64::TBZ:
+  case ARM64::TBNZW:
+  case ARM64::TBZW:
+  case ARM64::TBNZX:
+  case ARM64::TBZX:
     return TBZDisplacementBits;
   case ARM64::CBNZW:
   case ARM64::CBZW:
@@ -379,7 +387,8 @@ bool ARM64BranchRelaxation::fixupConditi
                      << *BMI);
         BMI->getOperand(0).setMBB(DestBB);
         unsigned OpNum =
-            (MI->getOpcode() == ARM64::TBZ || MI->getOpcode() == ARM64::TBNZ)
+            (MI->getOpcode() == ARM64::TBZW || MI->getOpcode() == ARM64::TBNZW ||
+             MI->getOpcode() == ARM64::TBZX || MI->getOpcode() == ARM64::TBNZX)
                 ? 2
                 : 1;
         MI->getOperand(OpNum).setMBB(NewDest);
@@ -420,7 +429,8 @@ bool ARM64BranchRelaxation::fixupConditi
   MachineInstrBuilder MIB = BuildMI(
       MBB, DebugLoc(), TII->get(getOppositeConditionOpcode(MI->getOpcode())))
                                 .addOperand(MI->getOperand(0));
-  if (MI->getOpcode() == ARM64::TBZ || MI->getOpcode() == ARM64::TBNZ)
+  if (MI->getOpcode() == ARM64::TBZW || MI->getOpcode() == ARM64::TBNZW ||
+      MI->getOpcode() == ARM64::TBZX || MI->getOpcode() == ARM64::TBNZX)
     MIB.addOperand(MI->getOperand(1));
   if (MI->getOpcode() == ARM64::Bcc)
     invertBccCondition(MIB);

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td Mon May 19 10:58:15 2014
@@ -173,6 +173,14 @@ def CondCode : AsmOperandClass {
   let DiagnosticType = "InvalidCondCode";
 }
 
+// A 32-bit register pasrsed as 64-bit
+def GPR32as64Operand : AsmOperandClass {
+  let Name = "GPR32as64";
+}
+def GPR32as64 : RegisterOperand<GPR32> {
+  let ParserMatchClass = GPR32as64Operand;
+}
+
 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
 // are encoded as the eight bit value 'abcdefgh'.
@@ -1037,10 +1045,37 @@ def am_tbrcond : Operand<OtherVT> {
   let ParserMatchClass = BranchTarget14Operand;
 }
 
-class TestBranch<bit op, string asm, SDNode node>
-    : I<(outs), (ins GPR64:$Rt, imm0_63:$bit_off, am_tbrcond:$target),
+// AsmOperand classes to emit (or not) special diagnostics
+def TBZImm0_31Operand : AsmOperandClass {
+  let Name = "TBZImm0_31";
+  let PredicateMethod = "isImm0_31";
+  let RenderMethod = "addImm0_31Operands";
+}
+def TBZImm32_63Operand : AsmOperandClass {
+  let Name = "Imm32_63";
+  let DiagnosticType = "InvalidImm0_63";
+}
+
+class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
+  return (((uint32_t)Imm) < 32);
+}]> {
+  let ParserMatchClass = matcher;
+}
+
+def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
+def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
+
+def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
+  return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
+}]> {
+  let ParserMatchClass = TBZImm32_63Operand;
+}
+
+class BaseTestBranch<RegisterClass regtype, Operand immtype,
+                     bit op, string asm, SDNode node>
+    : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
        asm, "\t$Rt, $bit_off, $target", "",
-       [(node GPR64:$Rt, imm0_63:$bit_off, bb:$target)]>,
+       [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
       Sched<[WriteBr]> {
   let isBranch = 1;
   let isTerminator = 1;
@@ -1049,7 +1084,6 @@ class TestBranch<bit op, string asm, SDN
   bits<6> bit_off;
   bits<14> target;
 
-  let Inst{31}    = bit_off{5};
   let Inst{30-25} = 0b011011;
   let Inst{24}    = op;
   let Inst{23-19} = bit_off{4-0};
@@ -1059,6 +1093,24 @@ class TestBranch<bit op, string asm, SDN
   let DecoderMethod = "DecodeTestAndBranch";
 }
 
+multiclass TestBranch<bit op, string asm, SDNode node> {
+  def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
+    let Inst{31} = 0;
+  }
+
+  def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
+    let Inst{31} = 1;
+  }
+
+  // Alias X-reg with 0-31 imm to W-Reg.
+  def : InstAlias<asm # "\t$Rd, $imm, $target",
+                  (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
+                  tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
+  def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
+            (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
+            tbz_imm0_31_diag:$imm, bb:$target)>;
+}
+
 //---
 // Unconditional branch (immediate) instructions.
 //---

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp Mon May 19 10:58:15 2014
@@ -70,8 +70,10 @@ static void parseCondBranch(MachineInstr
     Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
     Cond.push_back(LastInst->getOperand(0));
     break;
-  case ARM64::TBZ:
-  case ARM64::TBNZ:
+  case ARM64::TBZW:
+  case ARM64::TBZX:
+  case ARM64::TBNZW:
+  case ARM64::TBNZX:
     Target = LastInst->getOperand(2).getMBB();
     Cond.push_back(MachineOperand::CreateImm(-1));
     Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
@@ -196,11 +198,17 @@ bool ARM64InstrInfo::ReverseBranchCondit
     case ARM64::CBNZX:
       Cond[1].setImm(ARM64::CBZX);
       break;
-    case ARM64::TBZ:
-      Cond[1].setImm(ARM64::TBNZ);
+    case ARM64::TBZW:
+      Cond[1].setImm(ARM64::TBNZW);
       break;
-    case ARM64::TBNZ:
-      Cond[1].setImm(ARM64::TBZ);
+    case ARM64::TBNZW:
+      Cond[1].setImm(ARM64::TBZW);
+      break;
+    case ARM64::TBZX:
+      Cond[1].setImm(ARM64::TBNZX);
+      break;
+    case ARM64::TBNZX:
+      Cond[1].setImm(ARM64::TBZX);
       break;
     }
   }
@@ -453,17 +461,24 @@ void ARM64InstrInfo::insertSelect(Machin
     switch (Cond[1].getImm()) {
     default:
       llvm_unreachable("Unknown branch opcode in Cond");
-    case ARM64::TBZ:
+    case ARM64::TBZW:
+    case ARM64::TBZX:
       CC = ARM64CC::EQ;
       break;
-    case ARM64::TBNZ:
+    case ARM64::TBNZW:
+    case ARM64::TBNZX:
       CC = ARM64CC::NE;
       break;
     }
     // cmp reg, #foo is actually ands xzr, reg, #1<<foo.
-    BuildMI(MBB, I, DL, get(ARM64::ANDSXri), ARM64::XZR)
-        .addReg(Cond[2].getReg())
-        .addImm(ARM64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64));
+    if (Cond[1].getImm() == ARM64::TBZW || Cond[1].getImm() == ARM64::TBNZW)
+      BuildMI(MBB, I, DL, get(ARM64::ANDSWri), ARM64::WZR)
+          .addReg(Cond[2].getReg())
+          .addImm(ARM64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32));
+    else
+      BuildMI(MBB, I, DL, get(ARM64::ANDSXri), ARM64::XZR)
+          .addReg(Cond[2].getReg())
+          .addImm(ARM64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64));
     break;
   }
   }

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h Mon May 19 10:58:15 2014
@@ -209,8 +209,10 @@ static inline bool isCondBranchOpcode(in
   case ARM64::CBZX:
   case ARM64::CBNZW:
   case ARM64::CBNZX:
-  case ARM64::TBZ:
-  case ARM64::TBNZ:
+  case ARM64::TBZW:
+  case ARM64::TBZX:
+  case ARM64::TBNZW:
+  case ARM64::TBNZX:
     return true;
   default:
     return false;

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td Mon May 19 10:58:15 2014
@@ -54,7 +54,7 @@ def SDT_ARM64Brcond  : SDTypeProfile<0,
                                      [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>,
                                       SDTCisVT<2, i32>]>;
 def SDT_ARM64cbz : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisVT<1, OtherVT>]>;
-def SDT_ARM64tbz : SDTypeProfile<0, 3, [SDTCisVT<0, i64>, SDTCisVT<1, i64>,
+def SDT_ARM64tbz : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>,
                                         SDTCisVT<2, OtherVT>]>;
 
 
@@ -1045,8 +1045,8 @@ defm CBNZ : CmpBranch<1, "cbnz", ARM64cb
 //===----------------------------------------------------------------------===//
 // Test-bit-and-branch instructions.
 //===----------------------------------------------------------------------===//
-def TBZ  : TestBranch<0, "tbz", ARM64tbz>;
-def TBNZ : TestBranch<1, "tbnz", ARM64tbnz>;
+defm TBZ  : TestBranch<0, "tbz", ARM64tbz>;
+defm TBNZ : TestBranch<1, "tbnz", ARM64tbnz>;
 
 //===----------------------------------------------------------------------===//
 // Unconditional branch (immediate) instructions.

Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Mon May 19 10:58:15 2014
@@ -563,6 +563,15 @@ public:
     int64_t Val = MCE->getValue();
     return (Val >= 0 && Val < 65536);
   }
+  bool isImm32_63() const {
+    if (!isImm())
+      return false;
+    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
+    if (!MCE)
+      return false;
+    int64_t Val = MCE->getValue();
+    return (Val >= 32 && Val < 64);
+  }
   bool isLogicalImm32() const {
     if (!isImm())
       return false;
@@ -812,6 +821,10 @@ public:
     return Kind == k_Register && Reg.isVector &&
       ARM64MCRegisterClasses[ARM64::FPR128_loRegClassID].contains(Reg.RegNum);
   }
+  bool isGPR32as64() const {
+    return Kind == k_Register && !Reg.isVector &&
+      ARM64MCRegisterClasses[ARM64::GPR64RegClassID].contains(Reg.RegNum);
+  }
 
   /// Is this a vector list with the type implicit (presumably attached to the
   /// instruction itself)?
@@ -1188,6 +1201,17 @@ public:
     Inst.addOperand(MCOperand::CreateReg(getReg()));
   }
 
+  void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    assert(ARM64MCRegisterClasses[ARM64::GPR64RegClassID].contains(getReg()));
+
+    const MCRegisterInfo *RI = Ctx.getRegisterInfo();
+    uint32_t Reg = RI->getRegClass(ARM64::GPR32RegClassID).getRegister(
+        RI->getEncodingValue(getReg()));
+
+    Inst.addOperand(MCOperand::CreateReg(Reg));
+  }
+
   void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     assert(ARM64MCRegisterClasses[ARM64::FPR128RegClassID].contains(getReg()));
@@ -1408,6 +1432,13 @@ public:
     Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
   }
 
+  void addImm32_63Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
+    assert(MCE && "Invalid constant immediate operand!");
+    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
+  }
+
   void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
@@ -3951,27 +3982,6 @@ bool ARM64AsmParser::MatchAndEmitInstruc
         }
       }
     }
-  }
-  // FIXME: Horrible hack for tbz and tbnz with Wn register operand.
-  //        InstAlias can't quite handle this since the reg classes aren't
-  //        subclasses.
-  if (NumOperands == 4 && (Tok == "tbz" || Tok == "tbnz")) {
-    ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
-    if (Op->isImm()) {
-      if (const MCConstantExpr *OpCE = dyn_cast<MCConstantExpr>(Op->getImm())) {
-        if (OpCE->getValue() < 32) {
-          // The source register can be Wn here, but the matcher expects a
-          // GPR64. Twiddle it here if necessary.
-          ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
-          if (Op->isReg()) {
-            unsigned Reg = getXRegFromWReg(Op->getReg());
-            Operands[1] = ARM64Operand::CreateReg(
-                Reg, false, Op->getStartLoc(), Op->getEndLoc(), getContext());
-            delete Op;
-          }
-        }
-      }
-    }
   }
   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
   //        InstAlias can't quite handle this since the reg classes aren't

Modified: llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp Mon May 19 10:58:15 2014
@@ -1512,7 +1512,10 @@ static DecodeStatus DecodeTestAndBranch(
   if (dst & (1 << (14 - 1)))
     dst |= ~((1LL << 14) - 1);
 
-  DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+  if (fieldFromInstruction(insn, 31, 1) == 0)
+    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+  else
+    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
   Inst.addOperand(MCOperand::CreateImm(bit));
   if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4))
     Inst.addOperand(MCOperand::CreateImm(dst));

Modified: llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp Mon May 19 10:58:15 2014
@@ -63,18 +63,6 @@ void ARM64InstPrinter::printInst(const M
       return;
     }
 
-  // TBZ/TBNZ should print the register operand as a Wreg if the bit
-  // number is < 32.
-  if ((Opcode == ARM64::TBNZ || Opcode == ARM64::TBZ) &&
-      MI->getOperand(1).getImm() < 32) {
-    MCInst newMI = *MI;
-    unsigned Reg = MI->getOperand(0).getReg();
-    newMI.getOperand(0).setReg(getWRegFromXReg(Reg));
-    printInstruction(&newMI, O);
-    printAnnotation(O, Annot);
-    return;
-  }
-
   // SBFM/UBFM should print to a nicer aliased form if possible.
   if (Opcode == ARM64::SBFMXri || Opcode == ARM64::SBFMWri ||
       Opcode == ARM64::UBFMXri || Opcode == ARM64::UBFMWri) {

Modified: llvm/trunk/test/CodeGen/ARM64/early-ifcvt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/early-ifcvt.ll?rev=209134&r1=209133&r2=209134&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM64/early-ifcvt.ll (original)
+++ llvm/trunk/test/CodeGen/ARM64/early-ifcvt.ll Mon May 19 10:58:15 2014
@@ -322,7 +322,7 @@ done:
 }
 
 ; CHECK: tbnz_32
-; CHECK: {{ands.*xzr,|tst}} x2, #0x80
+; CHECK: {{ands.*xzr,|tst}} w2, #0x80
 ; CHECK-NEXT: csel w0, w1, w0, ne
 ; CHECK-NEXT: ret
 define i32 @tbnz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
@@ -358,7 +358,7 @@ done:
 }
 
 ; CHECK: tbz_32
-; CHECK: {{ands.*xzr,|tst}} x2, #0x80
+; CHECK: {{ands.*xzr,|tst}} w2, #0x80
 ; CHECK-NEXT: csel w0, w1, w0, eq
 ; CHECK-NEXT: ret
 define i32 @tbz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {





More information about the llvm-commits mailing list