Skip to content

Commit f676e84

Browse files
authored
[TableGen] Fix operand constraint checking problem. (#85859)
Currently operand constraint checks on "$dest = $src" are inadvertently accepting any token that contains "=". This has surprising results, e.g, "$dest != $src" is accepted as a constraint but then treated as "=". This patch ensures that only exactly the token "=" is accepted.
1 parent c2483ed commit f676e84

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

llvm/test/TableGen/ConstraintChecking3.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ include "ConstraintChecking.inc"
44

55
// (This is illegal because the '=' has to be surrounded by whitespace)
66

7-
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Illegal format for tied-to constraint in 'Foo'
7+
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1=$dest2' in 'Foo'
88
def Foo : TestInstructionWithConstraints<"$dest1=$dest2">;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: not llvm-tblgen -gen-asm-writer -DT0 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s
2+
// RUN: not llvm-tblgen -gen-asm-writer -DT1 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK1
3+
// RUN: not llvm-tblgen -gen-asm-writer -DT2 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK2
4+
// RUN: not llvm-tblgen -gen-asm-writer -DT3 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK3
5+
// RUN: not llvm-tblgen -gen-asm-writer -DT4 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK4
6+
7+
include "ConstraintChecking.inc"
8+
9+
// Make sure exactly the token "=" appears.
10+
11+
#ifdef T0
12+
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1 != $src2' in 'Foo'
13+
def Foo : TestInstructionWithConstraints<"$dest1 != $src2">;
14+
#endif
15+
16+
#ifdef T1
17+
// CHECK1: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1 == $src2' in 'Foo'
18+
def Foo : TestInstructionWithConstraints<"$dest1 == $src2">;
19+
#endif
20+
21+
#ifdef T2
22+
// CHECK2: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '= $rhs' in 'Foo'
23+
def Foo : TestInstructionWithConstraints<"= $rhs">;
24+
#endif
25+
26+
#ifdef T3
27+
// CHECK3: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$lhs =' in 'Foo'
28+
def Foo : TestInstructionWithConstraints<"$lhs =">;
29+
#endif
30+
31+
#ifdef T4
32+
// CHECK4: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '=' in 'Foo'
33+
def Foo : TestInstructionWithConstraints<"=">;
34+
#endif

llvm/utils/TableGen/CodeGenInstruction.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,9 @@ static void ParseConstraint(StringRef CStr, CGIOperandList &Ops, Record *Rec) {
325325

326326
// Only other constraint is "TIED_TO" for now.
327327
StringRef::size_type pos = CStr.find_first_of('=');
328-
if (pos == StringRef::npos)
328+
if (pos == StringRef::npos || pos == 0 ||
329+
CStr.find_first_of(" \t", pos) != (pos + 1) ||
330+
CStr.find_last_of(" \t", pos) != (pos - 1))
329331
PrintFatalError(Rec->getLoc(), "Unrecognized constraint '" + CStr +
330332
"' in '" + Rec->getName() + "'");
331333
start = CStr.find_first_not_of(" \t");

0 commit comments

Comments
 (0)