-
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
[InstCombine] Treat lshr nneg
as ashr
in getBinOpsForFactorization
#75521
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesFixes #70582. Full diff: https://github.com/llvm/llvm-project/pull/75521.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 6ac1fdb9252bff..a7ddadc25de43c 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -610,7 +610,7 @@ static Value *getIdentityValue(Instruction::BinaryOps Opcode, Value *V) {
/// allow more factorization opportunities.
static Instruction::BinaryOps
getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op,
- Value *&LHS, Value *&RHS) {
+ Value *&LHS, Value *&RHS, BinaryOperator *OtherOp) {
assert(Op && "Expected a binary operator");
LHS = Op->getOperand(0);
RHS = Op->getOperand(1);
@@ -623,6 +623,13 @@ getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op,
}
// TODO: We can add other conversions e.g. shr => div etc.
}
+ if (Instruction::isBitwiseLogicOp(TopOpcode)) {
+ if (OtherOp && OtherOp->getOpcode() == Instruction::AShr &&
+ match(Op, m_LShr(m_NonNegative(), m_Value()))) {
+ // lshr nneg C, X --> ashr nneg C, X
+ return Instruction::AShr;
+ }
+ }
return Op->getOpcode();
}
@@ -963,9 +970,9 @@ Value *InstCombinerImpl::tryFactorizationFolds(BinaryOperator &I) {
Instruction::BinaryOps LHSOpcode, RHSOpcode;
if (Op0)
- LHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op0, A, B);
+ LHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op0, A, B, Op1);
if (Op1)
- RHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op1, C, D);
+ RHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op1, C, D, Op0);
// The instruction has the form "(A op' B) op (C op' D)". Try to factorize
// a common term.
diff --git a/llvm/test/Transforms/InstCombine/xor.ll b/llvm/test/Transforms/InstCombine/xor.ll
index 7c61401fca07c7..388755b832096c 100644
--- a/llvm/test/Transforms/InstCombine/xor.ll
+++ b/llvm/test/Transforms/InstCombine/xor.ll
@@ -1395,3 +1395,48 @@ define i32 @ctlz_pow2_wrong_const(i32 %x) {
%r = xor i32 %z, 30
ret i32 %r
}
+
+; Tests from PR70582
+define i32 @tryFactorization_xor_ashr_lshr(i32 %a) {
+; CHECK-LABEL: @tryFactorization_xor_ashr_lshr(
+; CHECK-NEXT: [[XOR:%.*]] = ashr i32 -8, [[A:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %not = ashr i32 -3, %a
+ %shr1 = lshr i32 5, %a
+ %xor = xor i32 %not, %shr1
+ ret i32 %xor
+}
+
+define i32 @tryFactorization_xor_lshr_ashr(i32 %a) {
+; CHECK-LABEL: @tryFactorization_xor_lshr_ashr(
+; CHECK-NEXT: [[XOR:%.*]] = ashr i32 -8, [[A:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %not = ashr i32 -3, %a
+ %shr1 = lshr i32 5, %a
+ %xor = xor i32 %shr1, %not
+ ret i32 %xor
+}
+
+define i32 @tryFactorization_xor_lshr_lshr(i32 %a) {
+; CHECK-LABEL: @tryFactorization_xor_lshr_lshr(
+; CHECK-NEXT: [[XOR:%.*]] = lshr i32 -8, [[A:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %not = lshr i32 -3, %a
+ %shr1 = lshr i32 5, %a
+ %xor = xor i32 %not, %shr1
+ ret i32 %xor
+}
+
+define i32 @tryFactorization_xor_ashr_ashr(i32 %a) {
+; CHECK-LABEL: @tryFactorization_xor_ashr_ashr(
+; CHECK-NEXT: [[XOR:%.*]] = lshr i32 6, [[A:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
+;
+ %not = ashr i32 -3, %a
+ %shr1 = ashr i32 -5, %a
+ %xor = xor i32 %not, %shr1
+ ret i32 %xor
+}
|
nikic
approved these changes
Dec 14, 2023
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, but please add a negative test with ashr + lshr with negative LHS.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch reinterprets
lshr nneg C, X
asashr nneg C, X
to allow more factorization opportunities.Fixes #70582.