summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2018-06-26 11:38:41 +0000
committerTim Northover <tnorthover@apple.com>2018-06-26 11:38:41 +0000
commitbf5485811500e2534b17925aed80265d1b1c5af2 (patch)
tree80ff6f41c3cb81ae3400d88bfdc212a3258f2230
parent580f3eb2266336b59ad0d0cd1c1112b29165648b (diff)
downloadbcm5719-llvm-bf5485811500e2534b17925aed80265d1b1c5af2.tar.gz
bcm5719-llvm-bf5485811500e2534b17925aed80265d1b1c5af2.zip
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
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp15
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp5
-rw-r--r--llvm/test/MC/ARM/it-nv.s47
-rw-r--r--llvm/test/tools/llvm-objdump/it-nv.txt10
4 files changed, 76 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index f91397aca22..8a725876b68 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6348,6 +6348,21 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
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 3ffa702462c..f21dce3f3ad 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -729,10 +729,13 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
// 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;
diff --git a/llvm/test/MC/ARM/it-nv.s b/llvm/test/MC/ARM/it-nv.s
new file mode 100644
index 00000000000..dc717db3818
--- /dev/null
+++ b/llvm/test/MC/ARM/it-nv.s
@@ -0,0 +1,47 @@
+@ RUN: not llvm-mc -triple thumbv7m-apple-macho %s 2> %t.errs
+@ RUN: FileCheck %s < %t.errs --check-prefix=CHECK-ERRS
+
+@ CHECK-ERRS: error: unpredictable IT predicate sequence
+@ CHECK-ERRS: ite al
+@ CHECK-ERRS: error: unpredictable IT predicate sequence
+@ CHECK-ERRS: itee al
+@ CHECK-ERRS: error: unpredictable IT predicate sequence
+@ CHECK-ERRS: itet al
+@ CHECK-ERRS: error: unpredictable IT predicate sequence
+@ CHECK-ERRS: itte al
+@ CHECK-ERRS: error: unpredictable IT predicate sequence
+@ CHECK-ERRS: ittte al
+ ite al
+ itee al
+ itet al
+ itte al
+ ittte al
+
+@ CHECK-ERRS-NOT: error
+ it al
+ nop
+
+ itt al
+ nop
+ nop
+
+ ittt al
+ nop
+ nop
+ nop
+
+ itttt al
+ nop
+ nop
+ nop
+ nop
+
+ ite eq
+ nopeq
+ nopne
+
+ iteet hi
+ nophi
+ nopls
+ nopls
+ nophi
diff --git a/llvm/test/tools/llvm-objdump/it-nv.txt b/llvm/test/tools/llvm-objdump/it-nv.txt
new file mode 100644
index 00000000000..561f97bbb8b
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/it-nv.txt
@@ -0,0 +1,10 @@
+# RUN: llvm-objdump -macho -d %p/Inputs/it-nv.o | FileCheck %s
+
+# CHECK: ite al @ unpredictable IT predicate sequence
+# CHECK: itet al @ unpredictable IT predicate sequence
+# CHECK: itte al @ unpredictable IT predicate sequence
+# CHECK: ite eq{{$}}
+# CHECK: it al{{$}}
+# CHECK: itt al{{$}}
+# CHECK: ittt al{{$}}
+# CHECK: itttt al{{$}}
OpenPOWER on IntegriCloud