[llvm] [ConstraintElim] Decompose `sub nsw` (PR #118219)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 1 08:36:13 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
Closes https://github.com/llvm/llvm-project/issues/118211.
---
Full diff: https://github.com/llvm/llvm-project/pull/118219.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (+7)
- (added) llvm/test/Transforms/ConstraintElimination/sub-nsw.ll (+129)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 4884c23f16e12a..2f5ea8a2e46813 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -522,6 +522,13 @@ static Decomposition decompose(Value *V,
if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
return MergeResults(Op0, Op1, IsSigned);
+ if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
+ auto ResA = decompose(Op0, Preconditions, IsSigned, DL);
+ auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
+ ResA.sub(ResB);
+ return ResA;
+ }
+
ConstantInt *CI;
if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
auto Result = decompose(Op0, Preconditions, IsSigned, DL);
diff --git a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
new file mode 100644
index 00000000000000..3ea60d267043d9
--- /dev/null
+++ b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
@@ -0,0 +1,129 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
+
+define i1 @test_decompose_sub_nsw_sgt_nonneg(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_nonneg(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
+; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: ret i1 true
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %sub = sub nsw i32 %y, %x
+ %cond = icmp sgt i32 %sub, 10
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ %ret = icmp slt i32 %x, %y
+ ret i1 %ret
+
+if.else:
+ ret i1 true
+}
+
+define i1 @test_decompose_sub_nsw_sgt_zero(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
+; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 0
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: ret i1 true
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %sub = sub nsw i32 %y, %x
+ %cond = icmp sgt i32 %sub, 0
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ %ret = icmp slt i32 %x, %y
+ ret i1 %ret
+
+if.else:
+ ret i1 true
+}
+
+define i1 @test_decompose_sub_nsw_sgt_zero_inv(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero_inv(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
+; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: ret i1 false
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %sub = sub nsw i32 %y, %x
+ %cond = icmp sgt i32 %sub, 10
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ %ret = icmp sge i32 %x, %y
+ ret i1 %ret
+
+if.else:
+ ret i1 true
+}
+
+define i1 @test_decompose_sub_nonsw_sgt_zero(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @test_decompose_sub_nonsw_sgt_zero(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y]], [[X]]
+; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i1 [[RET]]
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %sub = sub i32 %y, %x
+ %cond = icmp sgt i32 %sub, 10
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ %ret = icmp slt i32 %x, %y
+ ret i1 %ret
+
+if.else:
+ ret i1 true
+}
+
+define i1 @test_decompose_sub_nsw_sgt_neg(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_neg(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
+; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], -10
+; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i1 [[RET]]
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %sub = sub nsw i32 %y, %x
+ %cond = icmp sgt i32 %sub, -10
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ %ret = icmp slt i32 %x, %y
+ ret i1 %ret
+
+if.else:
+ ret i1 true
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/118219
More information about the llvm-commits
mailing list