[llvm] f12684d - [ConstraintElim] Support signed decomposition of `add nsw`.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 15 10:34:25 PDT 2022
Author: Florian Hahn
Date: 2022-10-15T18:34:03+01:00
New Revision: f12684d36ef3d9c40963993f3c891656ffa87f94
URL: https://github.com/llvm/llvm-project/commit/f12684d36ef3d9c40963993f3c891656ffa87f94
DIFF: https://github.com/llvm/llvm-project/commit/f12684d36ef3d9c40963993f3c891656ffa87f94.diff
LOG: [ConstraintElim] Support signed decomposition of `add nsw`.
Add support decomposition for `add nsw` for signed queries.
`add nsw` won't wrap and can be directly added to the signed
system.
Added:
Modified:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/add-nsw.ll
llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 81b15c0bfc5c0..d2f4e735cd6c6 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -326,12 +326,28 @@ static SmallVector<DecompEntry, 4>
decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
bool IsSigned, const DataLayout &DL) {
+ auto MergeResults = [&Preconditions, IsSigned,
+ DL](Value *A, Value *B,
+ bool IsSignedB) -> SmallVector<DecompEntry, 4> {
+ auto ResA = decompose(A, Preconditions, IsSigned, DL);
+ auto ResB = decompose(B, Preconditions, IsSignedB, DL);
+ if (ResA.empty() || ResB.empty())
+ return {};
+ ResA[0].Coefficient += ResB[0].Coefficient;
+ append_range(ResA, drop_begin(ResB));
+ return ResA;
+ };
+
// Decompose \p V used with a signed predicate.
if (IsSigned) {
if (auto *CI = dyn_cast<ConstantInt>(V)) {
if (canUseSExt(CI))
return {{CI->getSExtValue(), nullptr}};
}
+ Value *Op0;
+ Value *Op1;
+ if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
+ return MergeResults(Op0, Op1, IsSigned);
return {{0, nullptr}, {1, V}};
}
@@ -352,17 +368,6 @@ decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
V = Op0;
}
- auto MergeResults = [&Preconditions, IsSigned,
- DL](Value *A, Value *B,
- bool IsSignedB) -> SmallVector<DecompEntry, 4> {
- auto ResA = decompose(A, Preconditions, IsSigned, DL);
- auto ResB = decompose(B, Preconditions, IsSignedB, DL);
- if (ResA.empty() || ResB.empty())
- return {};
- ResA[0].Coefficient += ResB[0].Coefficient;
- append_range(ResA, drop_begin(ResB));
- return ResA;
- };
Value *Op1;
ConstantInt *CI;
if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
diff --git a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
index be65c383c48f4..6e5e15223093e 100644
--- a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
+++ b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
@@ -1,7 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
-define void @test.not.uge.ult(i8 %start, i8 %low, i8 %high) {
+declare void @use(i1)
+
+define void @test.not.uge.ult(i8 %start, i8 %high) {
; CHECK-LABEL: @test.not.uge.ult(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
@@ -52,7 +54,7 @@ if.end: ; preds = %entry
ret void
}
-define void @test.not.sge.slt(i8 %start, i8 %low, i8 %high) {
+define void @test.not.sge.slt(i8 %start, i8 %high) {
; CHECK-LABEL: @test.not.sge.slt(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
@@ -62,16 +64,16 @@ define void @test.not.sge.slt(i8 %start, i8 %low, i8 %high) {
; CHECK-NEXT: ret void
; CHECK: if.end:
; CHECK-NEXT: [[T_0:%.*]] = icmp slt i8 [[START]], [[HIGH]]
-; CHECK-NEXT: call void @use(i1 [[T_0]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1
; CHECK-NEXT: [[T_1:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
-; CHECK-NEXT: call void @use(i1 [[T_1]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], 2
; CHECK-NEXT: [[T_2:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
-; CHECK-NEXT: call void @use(i1 [[T_2]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], 3
; CHECK-NEXT: [[T_3:%.*]] = icmp slt i8 [[START_3]], [[HIGH]]
-; CHECK-NEXT: call void @use(i1 [[T_3]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], 4
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 [[C_4]])
@@ -118,10 +120,10 @@ define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) {
; CHECK: if.then.2:
; CHECK-NEXT: [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]]
; CHECK-NEXT: [[T_0:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
-; CHECK-NEXT: call void @use(i1 [[T_0]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]]
; CHECK-NEXT: [[T_1:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
-; CHECK-NEXT: call void @use(i1 [[T_1]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]]
; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]]
; CHECK-NEXT: call void @use(i1 [[C_4]])
@@ -200,4 +202,47 @@ if.end: ; preds = %entry
ret void
}
-declare void @use(i1)
+define void @test.sge.slt.add.neg(i8 %start, i8 %high) {
+; CHECK-LABEL: @test.sge.slt.add.neg(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], -3
+; CHECK-NEXT: [[C_1:%.*]] = icmp slt i8 [[ADD_PTR_I]], [[HIGH:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
+; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[START]], [[HIGH]]
+; CHECK-NEXT: call void @use(i1 [[C_2]])
+; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1
+; CHECK-NEXT: [[C_3:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT: call void @use(i1 [[C_3]])
+; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], -2
+; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT: call void @use(i1 [[C_4]])
+; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], -3
+; CHECK-NEXT: [[T_1:%.*]] = icmp slt i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], -4
+; CHECK-NEXT: [[T_2:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: ret void
+;
+entry:
+ %add.ptr.i = add nsw i8 %start, -3
+ %c.1 = icmp slt i8 %add.ptr.i, %high
+ call void @llvm.assume(i1 %c.1)
+ %c.2 = icmp slt i8 %start, %high
+ call void @use(i1 %c.2)
+ %start.1 = add nsw i8 %start, 1
+ %c.3 = icmp slt i8 %start.1, %high
+ call void @use(i1 %c.3)
+ %start.2 = add nsw i8 %start, -2
+ %c.4 = icmp slt i8 %start.2, %high
+ call void @use(i1 %c.4)
+ %start.3 = add nsw i8 %start, -3
+ %t.1 = icmp slt i8 %start.3, %high
+ call void @use(i1 %t.1)
+ %start.4 = add nsw i8 %start, -4
+ %t.2 = icmp slt i8 %start.4, %high
+ call void @use(i1 %t.2)
+ ret void
+}
+
+declare void @llvm.assume(i1)
diff --git a/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll b/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll
index cec97d570c8b8..2dc9efd4df765 100644
--- a/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll
+++ b/llvm/test/Transforms/ConstraintElimination/mixed-signed-unsigned-predicates.ll
@@ -148,7 +148,7 @@ define i1 @test_add_nsw(i8 %start, i8 %low, i8 %high) {
; CHECK-NEXT: [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]]
; CHECK-NEXT: [[RES_0:%.*]] = xor i1 [[F_0]], [[F_1]]
; CHECK-NEXT: [[SC_1:%.*]] = icmp sgt i8 [[START]], [[HIGH]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[RES_0]], [[SC_1]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[RES_0]], false
; CHECK-NEXT: [[SC_2:%.*]] = icmp sge i8 [[START_1]], [[HIGH]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[SC_2]]
; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2
More information about the llvm-commits
mailing list