-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[ConstraintElimination] Decompose bitwise and or #126158
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Lee Wei (leewei05) ChangesAlive2: https://alive2.llvm.org/ce/z/XUp6KG @regehr Full diff: https://github.com/llvm/llvm-project/pull/126158.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index e0861fbedc560aa..78252ffa7ec785d 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -562,6 +562,18 @@ static Decomposition decompose(Value *V,
}
}
+ // (x | y) < 0 => (x < 0) || (y < 0)
+ if (match(V, m_Or(m_Value(Op0), m_Value(Op1)))) {
+ if (!isKnownNonNegative(Op0, DL) || !isKnownNonNegative(Op1, DL))
+ return MergeResults(Op0, Op1, IsSigned);
+ }
+
+ // (x & y) < 0 => (x < 0) && (y < 0)
+ if (match(V, m_And(m_Value(Op0), m_Value(Op1)))) {
+ if (!isKnownNonNegative(Op0, DL) && !isKnownNonNegative(Op1, DL))
+ return MergeResults(Op0, Op1, IsSigned);
+ }
+
return {V, IsKnownNonNegative};
}
diff --git a/llvm/test/Transforms/ConstraintElimination/and.ll b/llvm/test/Transforms/ConstraintElimination/and.ll
index f9824df3975e97a..9d89f8e5d372150 100644
--- a/llvm/test/Transforms/ConstraintElimination/and.ll
+++ b/llvm/test/Transforms/ConstraintElimination/and.ll
@@ -603,3 +603,91 @@ exit:
ret i1 %r.10
}
+
+define void @test_decompose_bitwise_and(i4 %x, i4 %y) {
+; CHECK-LABEL: @test_decompose_bitwise_and(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i4 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = icmp slt i4 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[AND]], label [[BB1:%.*]], label [[EXIT:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[F_1:%.*]] = icmp sge i4 [[X]], 0
+; CHECK-NEXT: [[F_2:%.*]] = icmp sge i4 [[Y]], 0
+; CHECK-NEXT: [[F_AND:%.*]] = and i1 false, [[F_2]]
+; CHECK-NEXT: call void @use(i1 [[F_AND]])
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: [[F_3:%.*]] = icmp slt i4 [[X]], 0
+; CHECK-NEXT: [[F_4:%.*]] = icmp slt i4 [[Y]], 0
+; CHECK-NEXT: [[F_AND_2:%.*]] = and i1 false, [[F_4]]
+; CHECK-NEXT: call void @use(i1 [[F_AND_2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %1 = and i4 %y, %x
+ %and = icmp slt i4 %1, 0
+ br i1 %and, label %bb1, label %exit
+
+bb1:
+ %f.1 = icmp sge i4 %x, 0
+ %f.2 = icmp sge i4 %y, 0
+ %f.and = and i1 %f.1, %f.2
+ call void @use(i1 %f.and)
+ ret void
+
+exit:
+ %f.3 = icmp slt i4 %x, 0
+ %f.4 = icmp slt i4 %y, 0
+ %f.and.2 = and i1 %f.3, %f.4
+ call void @use(i1 %f.and.2)
+ ret void
+}
+
+define void @test_decompose_nested_bitwise_and(i4 %x, i4 %y, i4 %z) {
+; CHECK-LABEL: @test_decompose_nested_bitwise_and(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i4 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[TMP0]], [[Z:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = icmp slt i4 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[AND]], label [[BB1:%.*]], label [[EXIT:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[F_1:%.*]] = icmp sge i4 [[X]], 0
+; CHECK-NEXT: [[F_2:%.*]] = icmp sge i4 [[Y]], 0
+; CHECK-NEXT: [[F_3:%.*]] = icmp sge i4 [[Z]], 0
+; CHECK-NEXT: [[F_AND:%.*]] = and i1 [[F_1]], [[F_2]]
+; CHECK-NEXT: [[F_AND_2:%.*]] = and i1 [[F_AND]], false
+; CHECK-NEXT: call void @use(i1 [[F_AND]])
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: [[F_4:%.*]] = icmp slt i4 [[X]], 0
+; CHECK-NEXT: [[F_5:%.*]] = icmp slt i4 [[Y]], 0
+; CHECK-NEXT: [[F_6:%.*]] = icmp slt i4 [[Z]], 0
+; CHECK-NEXT: [[F_AND_3:%.*]] = and i1 [[F_4]], [[F_5]]
+; CHECK-NEXT: [[F_AND_4:%.*]] = and i1 [[F_AND_3]], false
+; CHECK-NEXT: call void @use(i1 [[F_AND_4]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %1 = and i4 %y, %x
+ %2 = and i4 %1, %z
+ %and = icmp slt i4 %2, 0
+ br i1 %and, label %bb1, label %exit
+
+bb1:
+ %f.1 = icmp sge i4 %x, 0
+ %f.2 = icmp sge i4 %y, 0
+ %f.3 = icmp sge i4 %z, 0
+ %f.and = and i1 %f.1, %f.2
+ %f.and.2 = and i1 %f.and, %f.3
+ call void @use(i1 %f.and)
+ ret void
+
+exit:
+ %f.4 = icmp slt i4 %x, 0
+ %f.5 = icmp slt i4 %y, 0
+ %f.6 = icmp slt i4 %z, 0
+ %f.and.3 = and i1 %f.4, %f.5
+ %f.and.4 = and i1 %f.and.3, %f.6
+ call void @use(i1 %f.and.4)
+ ret void
+}
diff --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Transforms/ConstraintElimination/or.ll
index b401d6f18136958..37fecb0348b3b1c 100644
--- a/llvm/test/Transforms/ConstraintElimination/or.ll
+++ b/llvm/test/Transforms/ConstraintElimination/or.ll
@@ -808,3 +808,91 @@ end: ; preds = %entry
ret void
}
+
+define void @test_decompose_bitwise_or(i4 %x, i4 %y) {
+; CHECK-LABEL: @test_decompose_bitwise_or(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = or i4 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = icmp slt i4 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[EXIT:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[F_1:%.*]] = icmp slt i4 [[X]], 0
+; CHECK-NEXT: [[F_2:%.*]] = icmp slt i4 [[Y]], 0
+; CHECK-NEXT: [[F_OR:%.*]] = or i1 true, [[F_2]]
+; CHECK-NEXT: call void @use(i1 [[F_OR]])
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: [[F_3:%.*]] = icmp sge i4 [[X]], 0
+; CHECK-NEXT: [[F_4:%.*]] = icmp sge i4 [[Y]], 0
+; CHECK-NEXT: [[F_OR_2:%.*]] = or i1 true, [[F_4]]
+; CHECK-NEXT: call void @use(i1 [[F_OR_2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %1 = or i4 %y, %x
+ %or = icmp slt i4 %1, 0
+ br i1 %or, label %bb1, label %exit
+
+bb1:
+ %f.1 = icmp slt i4 %x, 0
+ %f.2 = icmp slt i4 %y, 0
+ %f.or = or i1 %f.1, %f.2
+ call void @use(i1 %f.or)
+ ret void
+
+exit:
+ %f.3 = icmp sge i4 %x, 0
+ %f.4 = icmp sge i4 %y, 0
+ %f.or.2 = or i1 %f.3, %f.4
+ call void @use(i1 %f.or.2)
+ ret void
+}
+
+define void @test_decompose_nested_bitwise_or(i4 %x, i4 %y, i4 %z) {
+; CHECK-LABEL: @test_decompose_nested_bitwise_or(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = or i4 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = or i4 [[TMP0]], [[Z:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = icmp slt i4 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[EXIT:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[F_1:%.*]] = icmp slt i4 [[X]], 0
+; CHECK-NEXT: [[F_2:%.*]] = icmp slt i4 [[Y]], 0
+; CHECK-NEXT: [[F_3:%.*]] = icmp slt i4 [[Z]], 0
+; CHECK-NEXT: [[F_OR:%.*]] = or i1 [[F_1]], [[F_2]]
+; CHECK-NEXT: [[F_OR_2:%.*]] = or i1 [[F_OR]], true
+; CHECK-NEXT: call void @use(i1 [[F_OR_2]])
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: [[F_4:%.*]] = icmp sge i4 [[X]], 0
+; CHECK-NEXT: [[F_5:%.*]] = icmp sge i4 [[Y]], 0
+; CHECK-NEXT: [[F_6:%.*]] = icmp sge i4 [[Z]], 0
+; CHECK-NEXT: [[F_OR_3:%.*]] = or i1 [[F_4]], [[F_5]]
+; CHECK-NEXT: [[F_OR_4:%.*]] = or i1 [[F_OR_3]], true
+; CHECK-NEXT: call void @use(i1 [[F_OR_4]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %1 = or i4 %y, %x
+ %2 = or i4 %1, %z
+ %or = icmp slt i4 %2, 0
+ br i1 %or, label %bb1, label %exit
+
+bb1:
+ %f.1 = icmp slt i4 %x, 0
+ %f.2 = icmp slt i4 %y, 0
+ %f.3 = icmp slt i4 %z, 0
+ %f.or = or i1 %f.1, %f.2
+ %f.or.2 = or i1 %f.or, %f.3
+ call void @use(i1 %f.or.2)
+ ret void
+
+exit:
+ %f.4 = icmp sge i4 %x, 0
+ %f.5 = icmp sge i4 %y, 0
+ %f.6 = icmp sge i4 %z, 0
+ %f.or.3 = or i1 %f.4, %f.5
+ %f.or.4 = or i1 %f.or.3, %f.6
+ call void @use(i1 %f.or.4)
+ ret void
+}
|
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.
!isKnownNonNegative(X)
doesn't meanX is negative
. You should useisKnownNegative
instead.MergeResults
only works for add.decompose
is used to decompose a value into the sum of variables and a constant offset. I guess @fhahn meant to decompose the constraint!(X | Y < 0)
intoX < 0
andY < 0
. You can do this inConstraintInfo::addFact
.
Thanks for the pointers! I should probably ask before implement this.. Let me try to re-implement this. |
Alive2: https://alive2.llvm.org/ce/z/XUp6KG
Fixes: #118114
@regehr