@@ -827,28 +827,34 @@ static Instruction *foldIDivShl(BinaryOperator &I,
827
827
Type *Ty = I.getType ();
828
828
829
829
// With appropriate no-wrap constraints, remove a common factor in the
830
- // dividend and divisor that is disguised as a left-shift .
830
+ // dividend and divisor that is disguised as a left-shifted value .
831
831
Value *X, *Y, *Z;
832
- if (match (Op1, m_Shl (m_Value (X), m_Value (Z))) &&
833
- match (Op0, m_c_Mul (m_Specific (X), m_Value (Y)))) {
834
- // Both operands must have the matching no-wrap for this kind of division.
835
- auto *Mul = cast<OverflowingBinaryOperator>(Op0);
836
- auto *Shl = cast<OverflowingBinaryOperator>(Op1);
837
- bool HasNUW = Mul->hasNoUnsignedWrap () && Shl->hasNoUnsignedWrap ();
838
- bool HasNSW = Mul->hasNoSignedWrap () && Shl->hasNoSignedWrap ();
839
-
840
- // (X * Y) u/ (X << Z) --> Y u>> Z
841
- if (!IsSigned && HasNUW)
842
- return BinaryOperator::CreateLShr (Y, Z);
843
-
844
- // (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
845
- if (IsSigned && HasNSW && (Op0->hasOneUse () || Op1->hasOneUse ())) {
846
- Value *Shl = Builder.CreateShl (ConstantInt::get (Ty, 1 ), Z);
847
- return BinaryOperator::CreateSDiv (Y, Shl);
848
- }
832
+ if (!match (Op1, m_Shl (m_Value (X), m_Value (Z))) ||
833
+ !match (Op0, m_c_Mul (m_Specific (X), m_Value (Y))))
834
+ return nullptr ;
835
+
836
+ // Both operands must have the matching no-wrap for this kind of division.
837
+ Instruction *Ret = nullptr ;
838
+ auto *Mul = cast<OverflowingBinaryOperator>(Op0);
839
+ auto *Shl = cast<OverflowingBinaryOperator>(Op1);
840
+ bool HasNUW = Mul->hasNoUnsignedWrap () && Shl->hasNoUnsignedWrap ();
841
+ bool HasNSW = Mul->hasNoSignedWrap () && Shl->hasNoSignedWrap ();
842
+
843
+ // (X * Y) u/ (X << Z) --> Y u>> Z
844
+ if (!IsSigned && HasNUW)
845
+ Ret = BinaryOperator::CreateLShr (Y, Z);
846
+
847
+ // (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
848
+ if (IsSigned && HasNSW && (Op0->hasOneUse () || Op1->hasOneUse ())) {
849
+ Value *Shl = Builder.CreateShl (ConstantInt::get (Ty, 1 ), Z);
850
+ Ret = BinaryOperator::CreateSDiv (Y, Shl);
849
851
}
850
852
851
- return nullptr ;
853
+ if (!Ret)
854
+ return nullptr ;
855
+
856
+ Ret->setIsExact (I.isExact ());
857
+ return Ret;
852
858
}
853
859
854
860
// / This function implements the transforms common to both integer division
0 commit comments