-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ValueTracking] Add support for insertelement
in isKnownNonZero
#87703
Conversation
Inserts don't modify the data, so if all elements that end up in the destination are non-zero the result is non-zero.
@llvm/pr-subscribers-llvm-analysis Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/87703.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5ad4da43bca7db..fce22e3af12027 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2751,6 +2751,29 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
return isKnownNonZero(U.get(), DemandedElts, NewDepth, RecQ);
});
}
+ case Instruction::InsertElement: {
+ if (isa<ScalableVectorType>(I->getType()))
+ break;
+
+ const Value *Vec = I->getOperand(0);
+ const Value *Elt = I->getOperand(1);
+ auto *CIdx = dyn_cast<ConstantInt>(I->getOperand(2));
+
+ unsigned NumElts = DemandedElts.getBitWidth();
+ APInt DemandedVecElts = DemandedElts;
+ bool SkipElt = false;
+ // If we know the index we are inserting too, clear it from Vec check.
+ if (CIdx && CIdx->getValue().ult(NumElts)) {
+ DemandedVecElts.clearBit(CIdx->getZExtValue());
+ SkipElt = !DemandedElts[CIdx->getZExtValue()];
+ }
+
+ // Result is zero if Elt is non-zero and rest of the demanded elts in Vec
+ // are non-zero.
+ return (SkipElt || isKnownNonZero(Elt, Depth, Q)) &&
+ (DemandedVecElts.isZero() ||
+ isKnownNonZero(Vec, DemandedVecElts, Depth, Q));
+ }
case Instruction::ExtractElement:
if (const auto *EEI = dyn_cast<ExtractElementInst>(I)) {
const Value *Vec = EEI->getVectorOperand();
diff --git a/llvm/test/Transforms/InstSimplify/known-non-zero.ll b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
index b647f11af4461d..a54309be3e4163 100644
--- a/llvm/test/Transforms/InstSimplify/known-non-zero.ll
+++ b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
@@ -166,3 +166,87 @@ A:
B:
ret i1 0
}
+
+define <2 x i1> @insert_nonzero0(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero0(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 1
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero1(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero1(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 0, i8 1>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_fail(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero_fail(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 0>
+; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_fail2(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero_fail2(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 0, i8 1>
+; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 0, i8 1>
+ %y = add i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_any_idx(<2 x i8> %xx, i8 %yy, i32 %idx) {
+; CHECK-LABEL: @insert_nonzero_any_idx(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 1>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 %idx
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_any_idx_fail(<2 x i8> %xx, i8 %yy, i32 %idx) {
+; CHECK-LABEL: @insert_nonzero_any_idx_fail(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 0>
+; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 [[IDX:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 %idx
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
|
@llvm/pr-subscribers-llvm-transforms Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/87703.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5ad4da43bca7db..fce22e3af12027 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2751,6 +2751,29 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
return isKnownNonZero(U.get(), DemandedElts, NewDepth, RecQ);
});
}
+ case Instruction::InsertElement: {
+ if (isa<ScalableVectorType>(I->getType()))
+ break;
+
+ const Value *Vec = I->getOperand(0);
+ const Value *Elt = I->getOperand(1);
+ auto *CIdx = dyn_cast<ConstantInt>(I->getOperand(2));
+
+ unsigned NumElts = DemandedElts.getBitWidth();
+ APInt DemandedVecElts = DemandedElts;
+ bool SkipElt = false;
+ // If we know the index we are inserting too, clear it from Vec check.
+ if (CIdx && CIdx->getValue().ult(NumElts)) {
+ DemandedVecElts.clearBit(CIdx->getZExtValue());
+ SkipElt = !DemandedElts[CIdx->getZExtValue()];
+ }
+
+ // Result is zero if Elt is non-zero and rest of the demanded elts in Vec
+ // are non-zero.
+ return (SkipElt || isKnownNonZero(Elt, Depth, Q)) &&
+ (DemandedVecElts.isZero() ||
+ isKnownNonZero(Vec, DemandedVecElts, Depth, Q));
+ }
case Instruction::ExtractElement:
if (const auto *EEI = dyn_cast<ExtractElementInst>(I)) {
const Value *Vec = EEI->getVectorOperand();
diff --git a/llvm/test/Transforms/InstSimplify/known-non-zero.ll b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
index b647f11af4461d..a54309be3e4163 100644
--- a/llvm/test/Transforms/InstSimplify/known-non-zero.ll
+++ b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
@@ -166,3 +166,87 @@ A:
B:
ret i1 0
}
+
+define <2 x i1> @insert_nonzero0(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero0(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 1
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero1(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero1(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 0, i8 1>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_fail(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero_fail(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 0>
+; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_fail2(<2 x i8> %xx, i8 %yy) {
+; CHECK-LABEL: @insert_nonzero_fail2(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 0, i8 1>
+; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 0, i8 1>
+ %y = add i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 0
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_any_idx(<2 x i8> %xx, i8 %yy, i32 %idx) {
+; CHECK-LABEL: @insert_nonzero_any_idx(
+; CHECK-NEXT: ret <2 x i1> zeroinitializer
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 1>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 %idx
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define <2 x i1> @insert_nonzero_any_idx_fail(<2 x i8> %xx, i8 %yy, i32 %idx) {
+; CHECK-LABEL: @insert_nonzero_any_idx_fail(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 0>
+; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 [[IDX:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[INS]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 0>
+ %y = add nuw i8 %yy, 1
+
+ %ins = insertelement <2 x i8> %x, i8 %y, i32 %idx
+ %r = icmp eq <2 x i8> %ins, zeroinitializer
+ ret <2 x i1> %r
+}
|
insertelement
in isKnownNonZero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
insertelement
inisKnownNonZero
; NFCinsertelement
inisKnownNonZero