[cfe-dev] CFG simplification question, and preservation of branching in the original code

Roman Lebedev via cfe-dev cfe-dev at lists.llvm.org
Sat Sep 21 05:49:27 PDT 2019


Actually, this should go to llvm-dev.

On Sat, Sep 21, 2019 at 3:48 PM Roman Lebedev <lebedev.ri at gmail.com> wrote:
>
> On Sat, Sep 21, 2019 at 3:18 PM Joan Lluch via cfe-dev
> <cfe-dev at lists.llvm.org> wrote:
> >
> > Hi all,
> >
> > For my custom architecture, I want to relax the CFG simplification pass, and any other passes replacing conditional branches.
> >
> > I found that the replacement of conditional branches by “select" and other instructions is often too aggressive, and this causes inefficient code for my target as in most cases branches would be cheaper.
> >
> > For example, considering the following c code:
> >
> > long test (long a, long b)
> > {
> >   int neg = 0;
> >   long res;
> >
> >   if (a < 0)
> >   {
> >     a = -a;
> >     neg = 1;
> >   }
> >
> >   res = a*b;
> >
> >   if (neg)
> >     res = -res;
> >
> >   return res;
> > }
> >
> >
> > This code can be simplified in c, but it’s just an example to show the point.
> >
> > The code above gets compiled like this (-Oz flag):
> >
> > ; Function Attrs: minsize norecurse nounwind optsize readnone
> > define dso_local i32 @test(i32 %a, i32 %b) local_unnamed_addr #0 {
> > entry:
> >   %cmp = icmp slt i32 %a, 0
> >   %sub = sub nsw i32 0, %a
> >   %a.addr.0 = select i1 %cmp, i32 %sub, i32 %a
> >   %mul = mul nsw i32 %a.addr.0, %b
> >   %sub2 = sub nsw i32 0, %mul
> >   %res.0 = select i1 %cmp, i32 %sub2, i32 %mul
> >   ret i32 %res.0
> > }
> >
> >
> > All branching was removed and replaced by ‘select’ instructions. For my architecture, it would be desirable to keep the original branches in most cases, because even simple 32 bit operations are too expensive to speculatively execute them, and branches are cheap.
> >
> > Setting  'phi-node-folding-threshold’ to 1 or even 0 (instead of the default 2), definitely improves the situation in many cases, but Clang still creates many instances of ‘select’ instructions, which are detrimental to my target. I am unsure about where are they created, as I believe that the simplifycfg pass does not longer create them.
> You definitively can't ban llvm passes/clang from creating select's.
>
> > So the question is: Are there any other hooks in clang, or custom code that I can implement, to relax the creation of ’select’ instructions and make it preserve branches in the original c code?
> I think this is backwards.
> Sure, you could maybe disable most of the folds that produce selects.
> That may be good for final codegen, but will also affect other passes
> since not everything deals with 2-node PHI as good as wit selects.
>
> But, what happens if you still get the select-y IR?
> Doesn't matter how, could be hand-written.
>
> I think you might want to instead aggressively convert selects into
> branches in backend.
>
> > Thanks,
> >
> > John
> Roman
>
> > _______________________________________________
> > LLVM Developers mailing list
> > llvm-dev at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> > _______________________________________________
> > cfe-dev mailing list
> > cfe-dev at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list