From: Toma Tabacu Date: Tue, 7 Apr 2015 12:10:11 +0000 (+0000) Subject: [TableGen] Prevent invalid code generation when emitting AssemblerPredicate conditions. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0e407e7bbff8bb26f25a8c5bc5926902abc44e92;p=oota-llvm.git [TableGen] Prevent invalid code generation when emitting AssemblerPredicate conditions. Summary: The loop which emits AssemblerPredicate conditions also links them together by emitting a '&&'. If the 1st predicate is not an AssemblerPredicate, while the 2nd one is, nothing gets emitted for the 1st one, but we still emit the '&&' because of the 2nd predicate. This generated code looks like "( && Cond2)" and is invalid. Reviewers: dsanders Reviewed By: dsanders Subscribers: dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D8294 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234312 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/TableGen/AsmPredicateCondsEmission.td b/test/TableGen/AsmPredicateCondsEmission.td new file mode 100644 index 00000000000..ba5898fbebd --- /dev/null +++ b/test/TableGen/AsmPredicateCondsEmission.td @@ -0,0 +1,31 @@ +// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s + +// Check that we don't generate invalid code of the form "( && Cond2)" when +// emitting AssemblerPredicate conditions. In the example below, the invalid +// code would be: "return ( && (Bits & arch::AssemblerCondition2));". + +include "llvm/Target/Target.td" + +def archInstrInfo : InstrInfo { } + +def arch : Target { + let InstructionSet = archInstrInfo; +} + +def Pred1 : Predicate<"Condition1">; +def Pred2 : Predicate<"Condition2">, + AssemblerPredicate<"AssemblerCondition2">; + +def foo : Instruction { + let Size = 2; + let OutOperandList = (outs); + let InOperandList = (ins); + field bits<16> Inst; + let Inst = 0xAAAA; + let AsmString = "foo"; + field bits<16> SoftFail = 0; + // This is the important bit: + let Predicates = [Pred1, Pred2]; +} + +// CHECK: return ((Bits & arch::AssemblerCondition2)); diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index c69b89b9bc0..a4a46b316f2 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -1112,6 +1112,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, unsigned Opc) const { ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); + bool IsFirstEmission = true; for (unsigned i = 0; i < Predicates->getSize(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); if (!Pred->getValue("AssemblerMatcherPredicate")) @@ -1122,7 +1123,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, if (!P.length()) continue; - if (i != 0) + if (!IsFirstEmission) o << " && "; StringRef SR(P); @@ -1133,6 +1134,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, pairs = pairs.second.split(','); } emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); + IsFirstEmission = false; } return Predicates->getSize() > 0; }