[llvm] [ConstraintElim] Decompose `sub nsw` (PR #118219)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 1 08:35:40 PST 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/118219

Closes https://github.com/llvm/llvm-project/issues/118211.


>From b18fb193b464a33be50d1722239d838db6a0645c Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 2 Dec 2024 00:21:27 +0800
Subject: [PATCH 1/2] [ConstraintElim] Add pre-commit tests. NFC.

---
 .../ConstraintElimination/sub-nsw.ll          | 132 ++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 llvm/test/Transforms/ConstraintElimination/sub-nsw.ll

diff --git a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
new file mode 100644
index 00000000000000..03f0b3dbdd83ab
--- /dev/null
+++ b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
@@ -0,0 +1,132 @@
+; 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:%.*]] = 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
+}
+
+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:%.*]] = 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, 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:%.*]] = icmp sge 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 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
+}

>From 0d326fc332dabd44db81349fdaf402cf70af1aad Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 2 Dec 2024 00:34:36 +0800
Subject: [PATCH 2/2] [ConstraintElim] Decompose `sub nsw`

---
 llvm/lib/Transforms/Scalar/ConstraintElimination.cpp  | 7 +++++++
 llvm/test/Transforms/ConstraintElimination/sub-nsw.ll | 9 +++------
 2 files changed, 10 insertions(+), 6 deletions(-)

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
index 03f0b3dbdd83ab..3ea60d267043d9 100644
--- a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
+++ b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll
@@ -9,8 +9,7 @@ define i1 @test_decompose_sub_nsw_sgt_nonneg(i32 %x, i32 %y) {
 ; 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-NEXT:    ret i1 true
 ; CHECK:       [[IF_ELSE]]:
 ; CHECK-NEXT:    ret i1 true
 ;
@@ -35,8 +34,7 @@ define i1 @test_decompose_sub_nsw_sgt_zero(i32 %x, i32 %y) {
 ; 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:%.*]] = icmp slt i32 [[X]], [[Y]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    ret i1 true
 ; CHECK:       [[IF_ELSE]]:
 ; CHECK-NEXT:    ret i1 true
 ;
@@ -61,8 +59,7 @@ define i1 @test_decompose_sub_nsw_sgt_zero_inv(i32 %x, i32 %y) {
 ; 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 sge i32 [[X]], [[Y]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    ret i1 false
 ; CHECK:       [[IF_ELSE]]:
 ; CHECK-NEXT:    ret i1 true
 ;



More information about the llvm-commits mailing list