Skip to content

Commit 3d5ce49

Browse files
author
Toma Tabacu
committedApr 7, 2015
[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 llvm-svn: 234312
1 parent 14ed198 commit 3d5ce49

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
2+
3+
// Check that we don't generate invalid code of the form "( && Cond2)" when
4+
// emitting AssemblerPredicate conditions. In the example below, the invalid
5+
// code would be: "return ( && (Bits & arch::AssemblerCondition2));".
6+
7+
include "llvm/Target/Target.td"
8+
9+
def archInstrInfo : InstrInfo { }
10+
11+
def arch : Target {
12+
let InstructionSet = archInstrInfo;
13+
}
14+
15+
def Pred1 : Predicate<"Condition1">;
16+
def Pred2 : Predicate<"Condition2">,
17+
AssemblerPredicate<"AssemblerCondition2">;
18+
19+
def foo : Instruction {
20+
let Size = 2;
21+
let OutOperandList = (outs);
22+
let InOperandList = (ins);
23+
field bits<16> Inst;
24+
let Inst = 0xAAAA;
25+
let AsmString = "foo";
26+
field bits<16> SoftFail = 0;
27+
// This is the important bit:
28+
let Predicates = [Pred1, Pred2];
29+
}
30+
31+
// CHECK: return ((Bits & arch::AssemblerCondition2));

‎llvm/utils/TableGen/FixedLenDecoderEmitter.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
11121112
unsigned Opc) const {
11131113
ListInit *Predicates =
11141114
AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates");
1115+
bool IsFirstEmission = true;
11151116
for (unsigned i = 0; i < Predicates->getSize(); ++i) {
11161117
Record *Pred = Predicates->getElementAsRecord(i);
11171118
if (!Pred->getValue("AssemblerMatcherPredicate"))
@@ -1122,7 +1123,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
11221123
if (!P.length())
11231124
continue;
11241125

1125-
if (i != 0)
1126+
if (!IsFirstEmission)
11261127
o << " && ";
11271128

11281129
StringRef SR(P);
@@ -1133,6 +1134,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
11331134
pairs = pairs.second.split(',');
11341135
}
11351136
emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
1137+
IsFirstEmission = false;
11361138
}
11371139
return Predicates->getSize() > 0;
11381140
}

0 commit comments

Comments
 (0)
Please sign in to comment.