ARM: diagnose unpredictable IT instructions
IT instructions are allowed to have the 'AL' predicate, but it must never
result in an 'NV' predicated instruction. Essentially this means that all
branches must be 't' rather than 'e' if the predicate is 'AL'.
This patch adds a diagnostic for this during assembly (error because parsing
hits an assertion if allowed to continue) and an annotation during disassembly.
llvm-svn: 335593
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index f91397ac..8a72587 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6348,6 +6348,21 @@
const unsigned Opcode = Inst.getOpcode();
switch (Opcode) {
+ case ARM::t2IT: {
+ // Encoding is unpredictable if it ever results in a notional 'NV'
+ // predicate. Since we don't parse 'NV' directly this means an 'AL'
+ // predicate with an "else" mask bit.
+ unsigned Cond = Inst.getOperand(0).getImm();
+ unsigned Mask = Inst.getOperand(1).getImm();
+
+ // Mask hasn't been modified to the IT instruction encoding yet so
+ // conditions only allowing a 't' are a block of 1s starting at bit 3
+ // followed by all 0s. Easiest way is to just list the 4 possibilities.
+ if (Cond == ARMCC::AL && Mask != 8 && Mask != 12 && Mask != 14 &&
+ Mask != 15)
+ return Error(Loc, "unpredictable IT predicate sequence");
+ break;
+ }
case ARM::LDRD:
case ARM::LDRD_PRE:
case ARM::LDRD_POST: {
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 3ffa702..f21dce3 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -729,10 +729,13 @@
// code and mask operands so that we can apply them correctly
// to the subsequent instructions.
if (MI.getOpcode() == ARM::t2IT) {
-
unsigned Firstcond = MI.getOperand(0).getImm();
unsigned Mask = MI.getOperand(1).getImm();
ITBlock.setITState(Firstcond, Mask);
+
+ // An IT instruction that would give a 'NV' predicate is unpredictable.
+ if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
+ CS << "unpredictable IT predicate sequence";
}
return Result;