[llvm] 01ceb98 - [InstCombine] Fold (zext (X +nuw C)) + -C --> zext(X) when zext has additional use. (#98533)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 12 07:40:32 PDT 2024
Author: Craig Topper
Date: 2024-07-12T07:40:29-07:00
New Revision: 01ceb9840a5b768232961444e3606a303ed4beed
URL: https://github.com/llvm/llvm-project/commit/01ceb9840a5b768232961444e3606a303ed4beed
DIFF: https://github.com/llvm/llvm-project/commit/01ceb9840a5b768232961444e3606a303ed4beed.diff
LOG: [InstCombine] Fold (zext (X +nuw C)) + -C --> zext(X) when zext has additional use. (#98533)
We have a general fold for (zext (X +nuw C2)) + C1 --> zext (X + (C2 +
trunc(C1)))
but this fold is disabled if the zext has an additional use.
If the two constants cancel, we can fold the whole expression to
zext(X) without increasing the number of instructions.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/add.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 0a73c58c07409..0a55f4762fdf0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -819,11 +819,16 @@ static Instruction *foldNoWrapAdd(BinaryOperator &Add,
Value *X;
const APInt *C1, *C2;
if (match(Op1, m_APInt(C1)) &&
- match(Op0, m_OneUse(m_ZExt(m_NUWAddLike(m_Value(X), m_APInt(C2))))) &&
+ match(Op0, m_ZExt(m_NUWAddLike(m_Value(X), m_APInt(C2)))) &&
C1->isNegative() && C1->sge(-C2->sext(C1->getBitWidth()))) {
- Constant *NewC =
- ConstantInt::get(X->getType(), *C2 + C1->trunc(C2->getBitWidth()));
- return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty);
+ APInt NewC = *C2 + C1->trunc(C2->getBitWidth());
+ // If the smaller add will fold to zero, we don't need to check one use.
+ if (NewC.isZero())
+ return new ZExtInst(X, Ty);
+ // Otherwise only do this if the existing zero extend will be removed.
+ if (Op0->hasOneUse())
+ return new ZExtInst(
+ Builder.CreateNUWAdd(X, ConstantInt::get(X->getType(), NewC)), Ty);
}
// More general combining of constants in the wide type.
diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 2f914a2e58867..adb61cd4b9692 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -955,8 +955,8 @@ define i64 @test41_multiuse_constants_cancel(i32 %a) {
; CHECK-LABEL: @test41_multiuse_constants_cancel(
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ADD]] to i64
-; CHECK-NEXT: [[REASS_ADD:%.*]] = shl nuw nsw i64 [[ZEXT]], 1
-; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw i64 [[REASS_ADD]], -1
+; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[A]] to i64
+; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]]
; CHECK-NEXT: ret i64 [[EXTRAUSE]]
;
%add = add nuw i32 %a, 1
More information about the llvm-commits
mailing list