[llvm] a4635ec - [ConstraintElim] Support `add nsw` for unsigned preds with positive ops.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 16 12:25:33 PDT 2022
Author: Florian Hahn
Date: 2022-10-16T20:25:14+01:00
New Revision: a4635ec7108c57adc248d203a39e809918a9d028
URL: https://github.com/llvm/llvm-project/commit/a4635ec7108c57adc248d203a39e809918a9d028
DIFF: https://github.com/llvm/llvm-project/commit/a4635ec7108c57adc248d203a39e809918a9d028.diff
LOG: [ConstraintElim] Support `add nsw` for unsigned preds with positive ops.
If both operands of an `add nsw` are known positive, it can be treated
the same as `add nuw` and added to the unsigned system.
https://alive2.llvm.org/ce/z/6gprff
Added:
Modified:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/add-nsw.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index e1290e9443f93..db1da1fd8e70f 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -373,6 +373,17 @@ decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
return MergeResults(Op0, Op1, IsSigned);
}
+ if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
+ if (!isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
+ Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
+ ConstantInt::get(Op0->getType(), 0));
+ if (!isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
+ Preconditions.emplace_back(CmpInst::ICMP_SGE, Op1,
+ ConstantInt::get(Op1->getType(), 0));
+
+ return MergeResults(Op0, Op1, IsSigned);
+ }
+
if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
canUseSExt(CI)) {
Preconditions.emplace_back(
diff --git a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
index c7f85719fa478..816c7ae912a18 100644
--- a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
+++ b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll
@@ -255,7 +255,7 @@ define i1 @test_ult_add_nsw_pos_1(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[T:%.*]] = icmp ult i16 [[START_EXT]], [[HIGH_EXT]]
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
%high.ext = zext i8 %high to i16
@@ -277,7 +277,7 @@ define i1 @test_ult_add_nsw_pos_1_assume_pos(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[T:%.*]] = icmp ult i8 [[START]], [[HIGH]]
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
%start.pos = icmp sge i8 %start, 0
@@ -317,7 +317,7 @@ define i1 @test_ult_add_nsw_pos_1_cmp_no_ext(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[T:%.*]] = icmp ult i8 [[START]], [[HIGH]]
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
%high.ext = zext i8 %high to i16
@@ -339,7 +339,7 @@ define i1 @test_ult_add_nsw_pos_2(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[F:%.*]] = icmp uge i16 [[START_EXT]], [[HIGH_EXT]]
-; CHECK-NEXT: ret i1 [[F]]
+; CHECK-NEXT: ret i1 false
;
entry:
%high.ext = zext i8 %high to i16
@@ -361,7 +361,7 @@ define i1 @test_ult_add_nsw_pos_2_assume_pos(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[F:%.*]] = icmp uge i8 [[START]], [[HIGH]]
-; CHECK-NEXT: ret i1 [[F]]
+; CHECK-NEXT: ret i1 false
;
entry:
%start.pos = icmp sge i8 %start, 0
@@ -383,7 +383,7 @@ define i1 @test_ult_add_nsw_pos_2_cmp_no_ext(i8 %start, i8 %high) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[START]], [[HIGH]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 false
;
entry:
%high.ext = zext i8 %high to i16
@@ -454,7 +454,7 @@ define i1 @test_ult_add_nsw_pos_4(i8 %start, i8 %high) {
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i16 [[START_EXT]], 2
; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[ADD_2]], [[HIGH_EXT]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 true
;
entry:
%high.ext = zext i8 %high to i16
@@ -478,7 +478,7 @@ define i1 @test_ult_add_nsw_pos_4_assume_pos(i8 %start, i8 %high) {
; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[START]], 2
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_2]], [[HIGH]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 true
;
entry:
%start.pos = icmp sge i8 %start, 0
@@ -663,3 +663,107 @@ entry:
%c = icmp ult i8 %add.off.2, %high
ret i1 %c
}
+
+define i1 @test_ult_add_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
+; CHECK-LABEL: @test_ult_add_nsw_var_8_all_pos(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
+; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
+; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
+; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
+; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]])
+; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %start.pos = icmp sge i8 %start, 0
+ call void @llvm.assume(i1 %start.pos)
+ %add = add nsw i8 %start, %off.2
+ %c.1 = icmp ult i8 %add, %high
+ call void @llvm.assume(i1 %c.1)
+ %off.1.pos = icmp sge i8 %off.1, 0
+ call void @llvm.assume(i1 %off.1.pos)
+ %off.2.pos = icmp sge i8 %off.2, 0
+ call void @llvm.assume(i1 %off.2.pos)
+ %off.1.ult = icmp ult i8 %off.1, %off.2
+ call void @llvm.assume(i1 %off.1.ult)
+
+ %add.off.2 = add nsw i8 %start, %off.1
+ %c = icmp ult i8 %add.off.2, %high
+ ret i1 %c
+}
+
+define i1 @test_ult_add_no_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
+; CHECK-LABEL: @test_ult_add_no_nsw_var_8_all_pos(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
+; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START]], [[OFF_2:%.*]]
+; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
+; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
+; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
+; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]])
+; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+entry:
+ %start.pos = icmp sge i8 %start, 0
+ call void @llvm.assume(i1 %start.pos)
+ %add = add i8 %start, %off.2
+ %c.1 = icmp ult i8 %add, %high
+ call void @llvm.assume(i1 %c.1)
+ %off.1.pos = icmp sge i8 %off.1, 0
+ call void @llvm.assume(i1 %off.1.pos)
+ %off.2.pos = icmp sge i8 %off.2, 0
+ call void @llvm.assume(i1 %off.2.pos)
+ %off.1.ult = icmp ult i8 %off.1, %off.2
+ call void @llvm.assume(i1 %off.1.ult)
+
+ %add.off.2 = add nsw i8 %start, %off.1
+ %c = icmp ult i8 %add.off.2, %high
+ ret i1 %c
+}
+
+define i1 @test_ult_add_nsw_var_9_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
+; CHECK-LABEL: @test_ult_add_nsw_var_9_all_pos(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
+; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
+; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
+; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
+; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+entry:
+ %start.pos = icmp sge i8 %start, 0
+ call void @llvm.assume(i1 %start.pos)
+ %add = add nsw i8 %start, %off.2
+ %c.1 = icmp ult i8 %add, %high
+ call void @llvm.assume(i1 %c.1)
+ %off.1.pos = icmp sge i8 %off.1, 0
+ call void @llvm.assume(i1 %off.1.pos)
+ %off.2.pos = icmp sge i8 %off.2, 0
+ call void @llvm.assume(i1 %off.2.pos)
+
+ %add.off.2 = add nsw i8 %start, %off.1
+ %c = icmp ult i8 %add.off.2, %high
+ ret i1 %c
+}
More information about the llvm-commits
mailing list