@@ -5808,6 +5808,63 @@ static Instruction *foldICmpPow2Test(ICmpInst &I,
5808
5808
return nullptr ;
5809
5809
}
5810
5810
5811
+ // / Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
5812
+ using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
5813
+ static void collectOffsetOp (Value *V, SmallVectorImpl<OffsetOp> &Offsets) {
5814
+ Instruction *Inst = dyn_cast<Instruction>(V);
5815
+ if (!Inst)
5816
+ return ;
5817
+ Constant *C;
5818
+
5819
+ switch (Inst->getOpcode ()) {
5820
+ case Instruction::Add:
5821
+ if (match (Inst->getOperand (1 ), m_ImmConstant (C)))
5822
+ if (Constant *NegC = ConstantExpr::getNeg (C))
5823
+ Offsets.emplace_back (Instruction::Add, NegC);
5824
+ break ;
5825
+ case Instruction::Xor:
5826
+ Offsets.emplace_back (Instruction::Xor, Inst->getOperand (1 ));
5827
+ Offsets.emplace_back (Instruction::Xor, Inst->getOperand (0 ));
5828
+ break ;
5829
+ default :
5830
+ break ;
5831
+ }
5832
+ }
5833
+
5834
+ // / Offset both sides of an equality icmp to see if we can save some
5835
+ // / instructions. icmp eq/ne X, Y -> icmp eq/ne X op C, Y op C Note: This
5836
+ // / operation should not introduce poison.
5837
+ static Instruction *foldICmpEqualityWithOffset (ICmpInst &I,
5838
+ InstCombiner::BuilderTy &Builder,
5839
+ const SimplifyQuery &SQ) {
5840
+ assert (I.isEquality () && " Expected an equality icmp" );
5841
+ Value *Op0 = I.getOperand (0 ), *Op1 = I.getOperand (1 );
5842
+ if (!Op0->getType ()->isIntOrIntVectorTy ())
5843
+ return nullptr ;
5844
+
5845
+ SmallVector<OffsetOp, 4 > OffsetOps;
5846
+ if (Op0->hasOneUse ())
5847
+ collectOffsetOp (Op0, OffsetOps);
5848
+ if (Op1->hasOneUse ())
5849
+ collectOffsetOp (Op1, OffsetOps);
5850
+ for (auto [BinOp, RHS] : OffsetOps) {
5851
+ auto BinOpc = static_cast <unsigned >(BinOp);
5852
+
5853
+ Value *Simplified0 = simplifyBinOp (BinOpc, Op0, RHS, SQ);
5854
+ if (!Simplified0 || Simplified0 == Op0)
5855
+ continue ;
5856
+
5857
+ Value *Simplified1 = simplifyBinOp (BinOpc, Op1, RHS, SQ);
5858
+ if (!Simplified1 || Simplified1 == Op1)
5859
+ continue ;
5860
+
5861
+ return new ICmpInst (static_cast <ICmpInst::Predicate>(I.getPredicate ()),
5862
+ Simplified0, Simplified1);
5863
+ }
5864
+
5865
+ return nullptr ;
5866
+ }
5867
+
5811
5868
Instruction *InstCombinerImpl::foldICmpEquality (ICmpInst &I) {
5812
5869
if (!I.isEquality ())
5813
5870
return nullptr ;
@@ -6054,6 +6111,10 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
6054
6111
: ConstantInt::getNullValue (A->getType ()));
6055
6112
}
6056
6113
6114
+ if (auto *Res = foldICmpEqualityWithOffset (
6115
+ I, Builder, getSimplifyQuery ().getWithInstruction (&I)))
6116
+ return Res;
6117
+
6057
6118
return nullptr ;
6058
6119
}
6059
6120
0 commit comments