[llvm-dev] optimisation issue in an llvm IR pass

Craig Topper via llvm-dev
Thu, 04 Jul 2019 00:28:40 -0000

This patch fixes the issue. I haven't checked our lit tests yet to see what
effect this has and if we can commit it.

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

@@ -2967,7 +2967,8 @@ SDValue DAGCombiner::visitADDCARRYLike(SDValue N0,
SDValue N1, SDValue CarryIn,

   // Iff the flag result is dead:

   // (addcarry (add|uaddo X, Y), 0, Carry) -> (addcarry X, Y, Carry)

   if ((N0.getOpcode() == ISD::ADD ||

-       (N0.getOpcode() == ISD::UADDO && N0.getResNo() == 0)) &&

+       (N0.getOpcode() == ISD::UADDO && N0.getResNo() == 0 &&

+        N0.getValue(1) != CarryIn)) &&

       isNullConstant(N1) && !N->hasAnyUseOfValue(1))

     return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(),

                        N0.getOperand(0), N0.getOperand(1), CarryIn);

~Craig


On Wed, Jul 3, 2019 at 9:40 AM Marc <mh at mh-sec.de> wrote:

> Hi Craig,
>
> On 03.07.19 17:33, Craig Topper wrote:
> > Don't the CreateICmp calls return a Value* with an i1 type? But
then
> > they are added to an i8 type? Not sure that works.
>
> I had that initially:
>  auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
>  auto carry = IRB.CreateZExt(cf, Int8Ty);
>  Incr = IRB.CreateAdd(Incr, carry);
> it makes no difference to the generated assembly
>
>
> > Have you tried using the llvm.uadd.with.overflow.i8 intrinsic?
>
> we have tried this:
>
>  CallInst *AddOv >
IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter,
> ConstantInt::get(Int8Ty, 1));
>  AddOv->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C, None));
>  Value *SumWithOverflowBit = AddOv;
>  Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0),
>  IRB.CreateZExt(IRB.CreateExtractValue(SumWithOverflowBit, 1), Int8Ty));
>
> but that generated exactly the same as
>
>  auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
>  Incr = IRB.CreateAdd(Incr, cf);
>
>
> All the above create (with llvm 6.0, 7 and 8):
>
>  mov    dl,BYTE PTR [rsi+rdi*1]
>  mov    ecx,edx // <- not needed
>  add    cl,0x1  // <- should be done to dl instead
>  adc    dl,0x1
>  mov    BYTE PTR [rsi+rdi*1],dl
>
>
> Thanks!
>
> Regards,
> Marc
>
> >
> > ~Craig
> >
> >
> > On Wed, Jul 3, 2019 at 4:01 AM Marc via llvm-dev
> > <llvm-dev at lists.llvm.org <mailto:llvm-dev at
lists.llvm.org>> wrote:
> >
> >     Hello,
> >
> >     I have an optimisation issue in an llvm IR pass - the issue being
> that
> >     unnecessary instructions are generated in the final assembly (with
> -O3).
> >
> >     I want to create the following assembly snippet:
> >
> >       mov    dl,BYTE PTR [rsi+rdi*1]
> >       add    dl,0x1
> >       adc    dl,0x0
> >       mov    BYTE PTR [rsi+rdi*1],dl
> >
> >     however what is created is (variant #1):
> >
> >       mov    dl,BYTE PTR [rsi+rdx*1]
> >       add    dl,0x1
> >       cmp    dl,0x1 // <- not needed
> >       adc    dl,0x0
> >       mov    BYTE PTR [rsi+rdi*1],dl
> >
> >     in variant #2 the following is created:
> >
> >      mov    dl,BYTE PTR [rsi+rdi*1]
> >      mov    ecx,edx // <- not needed
> >      add    cl,0x1  // <- should be done to dl instead
> >      adc    dl,0x1
> >      mov    BYTE PTR [rsi+rdi*1],dl
> >
> >     Far below are both variants with the full code around it, however
the
> >     difference in both variants is this:
> >
> >     //variant1
> >     auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
> >     Incr = IRB.CreateAdd(Incr, cf);
> >
> >     //variant2
> >     auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
> >     Incr = IRB.CreateAdd(Incr, cf);
> >
> >     //interestingly this totally different approach creates the same
> >     instructions as variant2
> >     CallInst *AddOv =
IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_over
> >     flow, Counter, ConstantInt::get(Int8Ty, 1));
> >     AddOv->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> None));
> >     Value *SumWithOverflowBit = AddOv;
> >     Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit,
0),
> >     IRB.CreateZExt(IRB.CreateExtractValue(SumWithOverflowBit, 1),
> Int8Ty));
> >
> >     So - How do I have to write the code that the target code has a
> chance
> >     of being generated?
> >     For me its the same result on LLVM 6.0 and 7.
> >
> >     Alternatively
> >       add    BYTE PTR [rsi+rdi*1],0x1
> >       adc    BYTE PTR [rsi+rdi*1],0x0
> >      would work as well.
> >
> >     Thank you very much!
> >
> >     Regards,
> >     Marc
> >
> >     -> Below now is the full llvm IR pass code
> >
> >     // vvv same code before both variants
> >     LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc);
> >     PrevLoc->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> None));
> >     Value *PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty());
> >
> >      LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
> >     MapPtr->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> None));
> >     Value *MapPtrIdx = IRB.CreateGEP(MapPtr,
IRB.CreateXor(PrevLocCasted,
> >     CurLoc));
> >
> >     LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
> >     Counter->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> None));
> >
> >     Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
> >     // ^^^ same code before both variants
> >
> >     // CODE FOR VARIANT #1
> >     auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
> >     Incr = IRB.CreateAdd(Incr, cf);
> >
> >     // CODE FOR VARIANT #2
> >     auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
> >     Incr = IRB.CreateAdd(Incr, cf);
> >
> >     // vvv same code after both variants
> >     IRB.CreateStore(Incr,
> >     MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> >     None));
> >     StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int32Ty,
cur_loc
> >>
> >     1), AFLPrevLoc);
> >     Store->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C,
> None));
> >     // ^^^ same code after both variants
> >
> >
> >     --
> >     Marc Heuse
> >     www.mh-sec.de <http://www.mh-sec.de>
> >
> >     PGP: AF3D 1D4C D810 F0BB 977D  3807 C7EE D0A0 6BE9 F573
> >     _______________________________________________
> >     LLVM Developers mailing list
> >     llvm-dev at lists.llvm.org <mailto:llvm-dev at
lists.llvm.org>
> >     https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> >
>
> --
> Marc Heuse
> Mobil: +49 177 9611560
> Fax: +49 30 37309726
> www.mh-sec.de
>
> Marc Heuse - IT-Security Consulting
> Winsstr. 68
> 10405 Berlin
>
> Ust.-Ident.-Nr.: DE244222388
> PGP: AF3D 1D4C D810 F0BB 977D  3807 C7EE D0A0 6BE9 F573
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20190703/0eeea0d3/attachment.html>