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

Marc via llvm-dev llvm-dev at lists.llvm.org
Wed Jul 3 04:01:32 PDT 2019


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

PGP: AF3D 1D4C D810 F0BB 977D  3807 C7EE D0A0 6BE9 F573


More information about the llvm-dev mailing list