[LLVM] Remove nuw neg (#86295)
This patch removes APIs that creating NUW neg. It is a trivial case because `sub nuw 0, X` always gets simplified into zero. I believe there is no optimization opportunities in the real-world applications that we can take advantage of the nuw flag. Motivated by https://github.com/llvm/llvm-project/pull/84792#discussion_r1524891134. Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=d1f182c895728d89c5c3d198b133e212a5d9d4a3&to=da7b7478b7cbb32c09d760f6b8d0e67901e0d533&stat=instructions:u
This commit is contained in:
@@ -146,6 +146,8 @@ Changes to the C API
|
||||
* ``LLVMGetPrologueData``
|
||||
* ``LLVMSetPrologueData``
|
||||
|
||||
* Deprecated ``LLVMConstNUWNeg`` and ``LLVMBuildNUWNeg``.
|
||||
|
||||
Changes to the CodeGen infrastructure
|
||||
-------------------------------------
|
||||
|
||||
|
||||
@@ -2316,7 +2316,9 @@ LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty);
|
||||
LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
|
||||
LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal);
|
||||
LLVM_ATTRIBUTE_C_DEPRECATED(
|
||||
LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal),
|
||||
"Use LLVMConstNull instead.");
|
||||
LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
@@ -4152,8 +4154,10 @@ LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
|
||||
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
const char *Name);
|
||||
LLVM_ATTRIBUTE_C_DEPRECATED(LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B,
|
||||
LLVMValueRef V,
|
||||
const char *Name),
|
||||
"Use LLVMBuildNeg + LLVMSetNUW instead.");
|
||||
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
|
||||
|
||||
@@ -1046,8 +1046,7 @@ public:
|
||||
///
|
||||
static Constant *getSizeOf(Type *Ty);
|
||||
|
||||
static Constant *getNeg(Constant *C, bool HasNUW = false,
|
||||
bool HasNSW = false);
|
||||
static Constant *getNeg(Constant *C, bool HasNSW = false);
|
||||
static Constant *getNot(Constant *C);
|
||||
static Constant *getAdd(Constant *C1, Constant *C2, bool HasNUW = false,
|
||||
bool HasNSW = false);
|
||||
@@ -1068,8 +1067,7 @@ public:
|
||||
static Constant *getAddrSpaceCast(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
|
||||
static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
|
||||
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
|
||||
static Constant *getNSWNeg(Constant *C) { return getNeg(C, /*HasNSW=*/true); }
|
||||
|
||||
static Constant *getNSWAdd(Constant *C1, Constant *C2) {
|
||||
return getAdd(C1, C2, false, true);
|
||||
|
||||
@@ -1712,18 +1712,13 @@ public:
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr,
|
||||
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
|
||||
|
||||
Value *CreateNeg(Value *V, const Twine &Name = "", bool HasNUW = false,
|
||||
bool HasNSW = false) {
|
||||
return CreateSub(Constant::getNullValue(V->getType()), V, Name, HasNUW,
|
||||
HasNSW);
|
||||
Value *CreateNeg(Value *V, const Twine &Name = "", bool HasNSW = false) {
|
||||
return CreateSub(Constant::getNullValue(V->getType()), V, Name,
|
||||
/*HasNUW=*/0, HasNSW);
|
||||
}
|
||||
|
||||
Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
|
||||
return CreateNeg(V, Name, false, true);
|
||||
}
|
||||
|
||||
Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
|
||||
return CreateNeg(V, Name, true, false);
|
||||
return CreateNeg(V, Name, /*HasNSW=*/true);
|
||||
}
|
||||
|
||||
Value *CreateFNeg(Value *V, const Twine &Name = "",
|
||||
|
||||
@@ -476,12 +476,6 @@ public:
|
||||
Instruction *InsertBefore = nullptr);
|
||||
static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name,
|
||||
BasicBlock *InsertAtEnd);
|
||||
static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
|
||||
BasicBlock::iterator InsertBefore);
|
||||
static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "",
|
||||
Instruction *InsertBefore = nullptr);
|
||||
static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
|
||||
BasicBlock *InsertAtEnd);
|
||||
static BinaryOperator *CreateNot(Value *Op, const Twine &Name,
|
||||
BasicBlock::iterator InsertBefore);
|
||||
static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "",
|
||||
|
||||
@@ -2520,10 +2520,10 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
|
||||
return pImpl->ExprConstants.getOrCreate(ShufTy, Key);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) {
|
||||
Constant *ConstantExpr::getNeg(Constant *C, bool HasNSW) {
|
||||
assert(C->getType()->isIntOrIntVectorTy() &&
|
||||
"Cannot NEG a nonintegral value!");
|
||||
return getSub(ConstantInt::get(C->getType(), 0), C, HasNUW, HasNSW);
|
||||
return getSub(ConstantInt::get(C->getType(), 0), C, /*HasNUW=*/false, HasNSW);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getNot(Constant *C) {
|
||||
|
||||
@@ -1648,7 +1648,7 @@ LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) {
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) {
|
||||
return wrap(ConstantExpr::getNUWNeg(unwrap<Constant>(ConstantVal)));
|
||||
return wrap(ConstantExpr::getNeg(unwrap<Constant>(ConstantVal)));
|
||||
}
|
||||
|
||||
|
||||
@@ -3557,7 +3557,10 @@ LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
|
||||
LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
const char *Name) {
|
||||
return wrap(unwrap(B)->CreateNUWNeg(unwrap(V), Name));
|
||||
Value *Neg = unwrap(B)->CreateNeg(unwrap(V), Name);
|
||||
if (auto *I = dyn_cast<BinaryOperator>(Neg))
|
||||
I->setHasNoUnsignedWrap();
|
||||
return wrap(Neg);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
||||
|
||||
@@ -3372,18 +3372,6 @@ BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name,
|
||||
return BinaryOperator::CreateNSWSub(Zero, Op, Name, InsertAtEnd);
|
||||
}
|
||||
|
||||
BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name,
|
||||
Instruction *InsertBefore) {
|
||||
Value *Zero = ConstantInt::get(Op->getType(), 0);
|
||||
return BinaryOperator::CreateNUWSub(Zero, Op, Name, InsertBefore);
|
||||
}
|
||||
|
||||
BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
Value *Zero = ConstantInt::get(Op->getType(), 0);
|
||||
return BinaryOperator::CreateNUWSub(Zero, Op, Name, InsertAtEnd);
|
||||
}
|
||||
|
||||
BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name,
|
||||
BasicBlock::iterator InsertBefore) {
|
||||
Constant *C = Constant::getAllOnesValue(Op->getType());
|
||||
|
||||
@@ -2524,9 +2524,10 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
|
||||
// sub (xor A, B), B ; flip bits if negative and subtract -1 (add 1)
|
||||
// --> (A < 0) ? -A : A
|
||||
Value *IsNeg = Builder.CreateIsNeg(A);
|
||||
// Copy the nuw/nsw flags from the sub to the negate.
|
||||
Value *NegA = Builder.CreateNeg(A, "", I.hasNoUnsignedWrap(),
|
||||
I.hasNoSignedWrap());
|
||||
// Copy the nsw flags from the sub to the negate.
|
||||
Value *NegA = I.hasNoUnsignedWrap()
|
||||
? Constant::getNullValue(A->getType())
|
||||
: Builder.CreateNeg(A, "", I.hasNoSignedWrap());
|
||||
return SelectInst::Create(IsNeg, NegA, A);
|
||||
}
|
||||
|
||||
|
||||
@@ -4250,10 +4250,11 @@ static Instruction *canonicalizeAbs(BinaryOperator &Xor,
|
||||
// xor (add A, Op1), Op1 ; add -1 and flip bits if negative
|
||||
// --> (A < 0) ? -A : A
|
||||
Value *IsNeg = Builder.CreateIsNeg(A);
|
||||
// Copy the nuw/nsw flags from the add to the negate.
|
||||
// Copy the nsw flags from the add to the negate.
|
||||
auto *Add = cast<BinaryOperator>(Op0);
|
||||
Value *NegA = Builder.CreateNeg(A, "", Add->hasNoUnsignedWrap(),
|
||||
Add->hasNoSignedWrap());
|
||||
Value *NegA = Add->hasNoUnsignedWrap()
|
||||
? Constant::getNullValue(A->getType())
|
||||
: Builder.CreateNeg(A, "", Add->hasNoSignedWrap());
|
||||
return SelectInst::Create(IsNeg, NegA, A);
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
@@ -1795,7 +1795,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
|
||||
// We don't have a "nabs" intrinsic, so negate if needed based on the
|
||||
// max/min operation.
|
||||
if (IID == Intrinsic::smin || IID == Intrinsic::umax)
|
||||
Abs = Builder.CreateNeg(Abs, "nabs", /* NUW */ false, IntMinIsPoison);
|
||||
Abs = Builder.CreateNeg(Abs, "nabs", IntMinIsPoison);
|
||||
return replaceInstUsesWith(CI, Abs);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ static Value *foldMulSelectToNegate(BinaryOperator &I,
|
||||
if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_One(), m_AllOnes())),
|
||||
m_Value(OtherOp)))) {
|
||||
bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();
|
||||
Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap);
|
||||
Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);
|
||||
return Builder.CreateSelect(Cond, OtherOp, Neg);
|
||||
}
|
||||
// mul (select Cond, -1, 1), OtherOp --> select Cond, -OtherOp, OtherOp
|
||||
@@ -113,7 +113,7 @@ static Value *foldMulSelectToNegate(BinaryOperator &I,
|
||||
if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_AllOnes(), m_One())),
|
||||
m_Value(OtherOp)))) {
|
||||
bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap();
|
||||
Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap);
|
||||
Value *Neg = Builder.CreateNeg(OtherOp, "", HasAnyNoWrap);
|
||||
return Builder.CreateSelect(Cond, Neg, OtherOp);
|
||||
}
|
||||
|
||||
@@ -452,9 +452,8 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
|
||||
// mul Y, (sext X) -> select X, -Y, 0
|
||||
if (match(&I, m_c_Mul(m_OneUse(m_SExt(m_Value(X))), m_Value(Y))) &&
|
||||
X->getType()->isIntOrIntVectorTy(1))
|
||||
return SelectInst::Create(
|
||||
X, Builder.CreateNeg(Y, "", /*HasNUW=*/false, I.hasNoSignedWrap()),
|
||||
ConstantInt::getNullValue(Op0->getType()));
|
||||
return SelectInst::Create(X, Builder.CreateNeg(Y, "", I.hasNoSignedWrap()),
|
||||
ConstantInt::getNullValue(Op0->getType()));
|
||||
|
||||
Constant *ImmC;
|
||||
if (match(Op1, m_ImmConstant(ImmC))) {
|
||||
|
||||
@@ -140,7 +140,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
|
||||
|
||||
// Integral constants can be freely negated.
|
||||
if (match(V, m_AnyIntegralConstant()))
|
||||
return ConstantExpr::getNeg(cast<Constant>(V), /*HasNUW=*/false,
|
||||
return ConstantExpr::getNeg(cast<Constant>(V),
|
||||
/*HasNSW=*/false);
|
||||
|
||||
// If we have a non-instruction, then give up.
|
||||
|
||||
@@ -497,7 +497,7 @@ static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) {
|
||||
// Is X in [IntMin, 0]? NOTE: INT_MIN is fine!
|
||||
if (Range.getSignedMax().isNonPositive()) {
|
||||
IRBuilder<> B(II);
|
||||
Value *NegX = B.CreateNeg(X, II->getName(), /*HasNUW=*/false,
|
||||
Value *NegX = B.CreateNeg(X, II->getName(),
|
||||
/*HasNSW=*/IsIntMinPoison);
|
||||
++NumAbs;
|
||||
II->replaceAllUsesWith(NegX);
|
||||
|
||||
Reference in New Issue
Block a user