[LLVMdev] predicates vs. requirements [TableGen, X86InstrInfo.td]

Daniel Sanders Daniel.Sanders at imgtec.com
Fri Sep 19 03:34:13 PDT 2014



> -----Original Message-----
> From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu]
> On Behalf Of Tom Stellard
> Sent: 19 September 2014 01:36
> To: Sanjay Patel
> Cc: llvmdev at cs.uiuc.edu
> Subject: Re: [LLVMdev] predicates vs. requirements [TableGen,
> X86InstrInfo.td]
> 
> On Thu, Sep 18, 2014 at 03:25:07PM -0600, Sanjay Patel wrote:
> > I tried to add an 'OptForSize' requirement to a pattern in X86InstrSSE.td,
> > but it appears to be ignored. However, the condition was detected when
> > specified as a predicate.
> >
> > So this doesn't work:
> >    def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))), (VMOVDDUPrm
> addr:
> > $src)>,
> >                  *Requires<[OptForSize**]>*;
> >
> > But this does:
> > *   let Predicates = [OptForSize] in* {
> >      def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))), (VMOVDDUPrm
> addr
> > :$src)>;
> >    }
> >
> > I see both forms used on some patterns like this:
> > *  let Predicates = [HasAVX] *in {
> >     def : Pat<(X86Movddup (loadv2f64 addr:$src)),
> >               (VMOVDDUPrm addr:$src)>, *Requires<[HasAVX]>*;
> >   }
> >
> > Is a predicate different than a requirement or is this a bug?
> >
> > There are existing patterns that specify 'OptForSize' with "Requires", but
> > they are not behaving as I expected.
> >
> > Example:
> >   // For scalar unary operations, fold a load into the operation
> >   // only in OptForSize mode. It eliminates an instruction, but it also
> >   // eliminates a whole-register clobber (the load), so it introduces a
> >   // partial register update condition.
> >   def : Pat<(f32 (fsqrt (load addr:$src))),
> >             (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
> >             Requires<[HasAVX, OptForSize]>;
> >
> > This is generated:
> >     vsqrtss    (%rdi), %xmm0, %xmm0
> >
> > regardless of whether I specify -Os or -O1 with clang.
> 
> You might want to take a look at the Mips target, it has a
> class called PredicateControl defined in Mips.td, which
> handles merging predicates together into a single list.
> 
> Maybe you could do something similar for x86.
> 
> -Tom

That's right, it's solving the same problem. I added it after I found several defs that attempted to add predicates but accidentally removed some of the existing ones at the same time.

The root of the problem is the way tablegen processes the declarations and assignments. tablegen creates an empty record and applies the subclasses in left-to-right order. Then it applies any 'let Foo = Bar in' statements. So given this code:
  let Predicates = [OptForSize] in {
     def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))), (VMOVDDUPrm addr:$src)>, Requires<[Foo]>, Requires<[Bar]>;
  }
the value of Predicates in the record goes through the following values:
* Undefined // Initial empty record
* []         // The Pat has been applied
* [Foo] // The first Requires<> has been applied.
* [Bar] // The second Requires<> has been applied.
* [OptForSize] // The let Predicates = ... in has been applied.




More information about the llvm-dev mailing list