This is an archive of the discontinued LLVM Phabricator instance.

[TableGen] Fix negation of simple predicates
ClosedPublic

Authored by evandro on Nov 29 2018, 4:14 PM.

Details

Summary

Simple predicates, such as those defined by CheckRegOperandSimple or CheckImmOperandSimple, were not being negated when used with CheckNot.

This change fixes this issue by defining the previously declared methods to handle simple predicates.

Diff Detail

Repository
rL LLVM

Event Timeline

evandro created this revision.Nov 29 2018, 4:14 PM

Hi Evandro.

The two new methods added by your patch are mostly equivalent to expandCheckImmOperand and expandCheckRegOperand.
Rather than introducing those new methods, I think a better fix is to add checks for null/empty operands in expandCheckImmOperand and expandCheckRegOperand.

Basically, I am thinking about something like this:

Index: TableGen/PredicateExpander.cpp
===================================================================
--- TableGen/PredicateExpander.cpp      (revision 347858)
+++ TableGen/PredicateExpander.cpp      (working copy)
@@ -31,14 +31,16 @@
 }

 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
                                               StringRef ImmVal,
                                               StringRef FunctionMapper) {
   if (!FunctionMapper.empty())
     OS << FunctionMapper << "(";
+  if (ImmVal.empty() && shouldNegate())
+    OS << '!';
   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
      << ").getImm()";

   OS << (FunctionMapper.empty() ? "" : ")");
   if (ImmVal.empty())
     return;
   OS << (shouldNegate() ? " != " : " == ") << ImmVal;
@@ -47,14 +49,16 @@
 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
                                               const Record *Reg,
                                               StringRef FunctionMapper) {
   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");

   if (!FunctionMapper.empty())
     OS << FunctionMapper << "(";
+  if (!Reg && shouldNegate())
+    OS << '!';
   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
      << ").getReg()";
   OS << (FunctionMapper.empty() ? "" : ")");
   if (!Reg)
     return;
   OS << (shouldNegate() ? " != " : " == ");
   const StringRef Str = Reg->getValueAsString("Namespace");

As a side note: your patch made me realize that the declarations of expandCheckRegOperandSimple and expandCheckImmOperandSimple in the header file are pretty much dead. In case, (if you agree with this alternative approach), your patch should be able to remove them from the header file.

-Andrea

I'm all for reusing code, but this is not any sophisticated algorithm, but mere streaming of data. I rather keep the additional methods and simplify the exiting ones to eliminate their special cases for the sake of maintenance. After all, complicating them is what resulted in this issue.

andreadb accepted this revision.Nov 30 2018, 12:07 PM

I'm all for reusing code, but this is not any sophisticated algorithm, but mere streaming of data. I rather keep the additional methods and simplify the exiting ones to eliminate their special cases for the sake of maintenance. After all, complicating them is what resulted in this issue.

Fair enough.

LGTM

This revision is now accepted and ready to land.Nov 30 2018, 12:07 PM
This revision was automatically updated to reflect the committed changes.