-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[GVN] Handle not in equality propagation #151942
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
base: main
Are you sure you want to change the base?
Conversation
looks good to me. |
@llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesLook through Fixes #143529. Full diff: https://github.com/llvm/llvm-project/pull/151942.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index fa6ee95d33d10..3a73b42455b0d 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2683,6 +2683,11 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
Worklist.emplace_back(A, ConstantInt::get(A->getType(), IsKnownTrue));
continue;
}
+
+ if (match(LHS, m_Not(m_Value(A)))) {
+ Worklist.emplace_back(A, ConstantInt::get(A->getType(), !IsKnownTrue));
+ continue;
+ }
}
return Changed;
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll
index 3babdd8173a21..15ffcbff1e157 100644
--- a/llvm/test/Transforms/GVN/condprop.ll
+++ b/llvm/test/Transforms/GVN/condprop.ll
@@ -999,5 +999,87 @@ loop.latch:
br label %loop
}
+define i1 @not_cond(i1 %c) {
+; CHECK-LABEL: @not_cond(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: br i1 [[C_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: ret i1 true
+;
+ %c.not = xor i1 %c, true
+ br i1 %c.not, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
+define i32 @not_cond_icmp(i32 %x) {
+; CHECK-LABEL: @not_cond_icmp(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
+; CHECK-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP]], true
+; CHECK-NEXT: br i1 [[CMP_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i32 [[X]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 42
+;
+ %cmp = icmp eq i32 %x, 42
+ %cmp.not = xor i1 %cmp, true
+ br i1 %cmp.not, label %if, label %else
+
+if:
+ ret i32 %x
+
+else:
+ ret i32 %x
+}
+
+define i1 @not_cond_logic1(i1 %c, i1 %d) {
+; CHECK-LABEL: @not_cond_logic1(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_NOT]], [[D:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %c.not = xor i1 %c, true
+ %and = and i1 %c.not, %d
+ br i1 %and, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
+define i1 @not_cond_logic2(i1 %c, i1 %d) {
+; CHECK-LABEL: @not_cond_logic2(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = or i1 [[C_NOT]], [[D:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 [[C]]
+; CHECK: else:
+; CHECK-NEXT: ret i1 true
+;
+ %c.not = xor i1 %c, true
+ %or = or i1 %c.not, %d
+ br i1 %or, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
declare void @use_bool(i1)
declare void @use_ptr(ptr)
|
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, thanks
Look through
not
when propagating equalities in GVN. Usually these will be canonicalized away, but they may be retained due to multi-use or involvement in logical expressions.Fixes #143529.