@@ -136,6 +136,50 @@ static bool optimizeAShrInst(Instruction *I) {
136136 return false ;
137137}
138138
139+ static bool optimizeICmp (ICmpInst *I) {
140+ auto *Ty = I->getOperand (0 )->getType ();
141+ if (!Ty->isIntegerTy (256 ))
142+ return false ;
143+
144+ if (I->getPredicate () == CmpInst::ICMP_ULT) {
145+ Value *X = nullptr ;
146+ const APInt *CAdd = nullptr , *CCmp = nullptr ;
147+
148+ // icmp ult (add x, CAdd), CCmp -> icmp eq (evm.signextend(b, x)), x
149+ // where CCmp is a power of 2 and CAdd is twice smaller than CCmp.
150+ if (match (I->getOperand (0 ), m_OneUse (m_c_Add (m_Value (X), m_APInt (CAdd)))) &&
151+ match (I->getOperand (1 ), m_APInt (CCmp)) && CCmp->isPowerOf2 () &&
152+ *CAdd == CCmp->lshr (1 )) {
153+ unsigned CCmpLog2 = CCmp->logBase2 ();
154+
155+ // If CCmpLog2 is not divisible by 8, cannot use signextend.
156+ if (CCmpLog2 % 8 != 0 )
157+ return false ;
158+
159+ IRBuilder<> Builder (I);
160+ unsigned ByteIdx = (CCmpLog2 / 8 ) - 1 ;
161+
162+ // ByteIdx should be in [0, 31].
163+ if (ByteIdx > 31 )
164+ return false ;
165+
166+ auto *B = ConstantInt::get (Ty, ByteIdx);
167+ auto *SignExtend =
168+ Builder.CreateIntrinsic (Ty, Intrinsic::evm_signextend, {B, X});
169+ auto *NewCmp = Builder.CreateICmp (CmpInst::ICMP_EQ, SignExtend, X);
170+ NewCmp->takeName (I);
171+ I->replaceAllUsesWith (NewCmp);
172+
173+ // Remove add after icmp. If to do otherwise, assert will be triggered.
174+ auto *ToRemove = cast<Instruction>(I->getOperand (0 ));
175+ I->eraseFromParent ();
176+ ToRemove->eraseFromParent ();
177+ return true ;
178+ }
179+ }
180+ return false ;
181+ }
182+
139183bool EVMCodegenPrepare::runOnFunction (Function &F) {
140184 bool Changed = false ;
141185 for (auto &BB : F) {
@@ -146,6 +190,8 @@ bool EVMCodegenPrepare::runOnFunction(Function &F) {
146190 }
147191 if (I.getOpcode () == Instruction::AShr)
148192 Changed |= optimizeAShrInst (&I);
193+ else if (I.getOpcode () == Instruction::ICmp)
194+ Changed |= optimizeICmp (cast<ICmpInst>(&I));
149195 }
150196 }
151197
0 commit comments