[llvm] [ConstraintElim] Decompose sext-like insts for signed predicates (PR #82344)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 03:23:19 PST 2024


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

Alive2: https://alive2.llvm.org/ce/z/A8dtGp
Fixes #82271.



>From b52c44700561f0215a42e8db2d09b111ae4565e0 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 20 Feb 2024 19:15:58 +0800
Subject: [PATCH 1/2] [ConstraintElim] Add pre-commit tests for PR82271. NFC.

---
 .../ConstraintElimination/minmax.ll           | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/llvm/test/Transforms/ConstraintElimination/minmax.ll b/llvm/test/Transforms/ConstraintElimination/minmax.ll
index 68513ea10ad0fe..ab3e9f381245be 100644
--- a/llvm/test/Transforms/ConstraintElimination/minmax.ll
+++ b/llvm/test/Transforms/ConstraintElimination/minmax.ll
@@ -601,6 +601,126 @@ else:
   ret i32 -1
 }
 
+define i64 @pr82271(i32 %a, i32 %b){
+; CHECK-LABEL: define i64 @pr82271
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
+; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
+; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i64 0
+;
+entry:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %then, label %else
+
+then:
+  %sa = sext i32 %a to i64
+  %sb = sext i32 %b to i64
+  %add = add nsw i64 %sa, 1
+  %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)
+  ret i64 %smax
+
+else:
+  ret i64 0
+}
+
+define i64 @pr82271_sext_zext_nneg(i32 %a, i32 %b){
+; CHECK-LABEL: define i64 @pr82271_sext_zext_nneg
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
+; CHECK-NEXT:    [[SB:%.*]] = zext nneg i32 [[B]] to i64
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
+; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i64 0
+;
+entry:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %then, label %else
+
+then:
+  %sa = sext i32 %a to i64
+  %sb = zext nneg i32 %b to i64
+  %add = add nsw i64 %sa, 1
+  %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)
+  ret i64 %smax
+
+else:
+  ret i64 0
+}
+
+define i64 @pr82271_zext_nneg(i32 %a, i32 %b){
+; CHECK-LABEL: define i64 @pr82271_zext_nneg
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[SA:%.*]] = zext nneg i32 [[A]] to i64
+; CHECK-NEXT:    [[SB:%.*]] = zext nneg i32 [[B]] to i64
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
+; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i64 0
+;
+entry:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %then, label %else
+
+then:
+  %sa = zext nneg i32 %a to i64
+  %sb = zext nneg i32 %b to i64
+  %add = add nsw i64 %sa, 1
+  %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)
+  ret i64 %smax
+
+else:
+  ret i64 0
+}
+
+define i64 @pr82271_zext(i32 %a, i32 %b){
+; CHECK-LABEL: define i64 @pr82271_zext
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[SA:%.*]] = zext i32 [[A]] to i64
+; CHECK-NEXT:    [[SB:%.*]] = zext i32 [[B]] to i64
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
+; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
+; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i64 0
+;
+entry:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %then, label %else
+
+then:
+  %sa = zext i32 %a to i64
+  %sb = zext i32 %b to i64
+  %add = add nsw i64 %sa, 1
+  %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)
+  ret i64 %smax
+
+else:
+  ret i64 0
+}
+
 declare i32 @llvm.smin.i32(i32, i32)
 declare i32 @llvm.smax.i32(i32, i32)
 declare i32 @llvm.umin.i32(i32, i32)

>From daac7109874559c22a8b77d3f931c6082440fdae Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 20 Feb 2024 19:17:05 +0800
Subject: [PATCH 2/2] [ConstraintElim] Decompose sext-like insts for signed
 predicates

---
 llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 7 +++++++
 llvm/test/Transforms/ConstraintElimination/minmax.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 db05c63f388fb1..c77245a76f4622 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -507,6 +507,13 @@ static Decomposition decompose(Value *V,
     }
     Value *Op0;
     Value *Op1;
+
+    if (match(V, m_SExt(m_Value(Op0))))
+      return Op0;
+
+    if (match(V, m_NNegZExt(m_Value(Op0))))
+      return {Op0, /*IsKnownNonNegative=*/true};
+
     if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
       return MergeResults(Op0, Op1, IsSigned);
 
diff --git a/llvm/test/Transforms/ConstraintElimination/minmax.ll b/llvm/test/Transforms/ConstraintElimination/minmax.ll
index ab3e9f381245be..029b6508a2106e 100644
--- a/llvm/test/Transforms/ConstraintElimination/minmax.ll
+++ b/llvm/test/Transforms/ConstraintElimination/minmax.ll
@@ -611,8 +611,7 @@ define i64 @pr82271(i32 %a, i32 %b){
 ; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
 ; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
-; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
-; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK-NEXT:    ret i64 [[SB]]
 ; CHECK:       else:
 ; CHECK-NEXT:    ret i64 0
 ;
@@ -641,8 +640,7 @@ define i64 @pr82271_sext_zext_nneg(i32 %a, i32 %b){
 ; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
 ; CHECK-NEXT:    [[SB:%.*]] = zext nneg i32 [[B]] to i64
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
-; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
-; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK-NEXT:    ret i64 [[SB]]
 ; CHECK:       else:
 ; CHECK-NEXT:    ret i64 0
 ;
@@ -671,8 +669,7 @@ define i64 @pr82271_zext_nneg(i32 %a, i32 %b){
 ; CHECK-NEXT:    [[SA:%.*]] = zext nneg i32 [[A]] to i64
 ; CHECK-NEXT:    [[SB:%.*]] = zext nneg i32 [[B]] to i64
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
-; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
-; CHECK-NEXT:    ret i64 [[SMAX]]
+; CHECK-NEXT:    ret i64 [[SB]]
 ; CHECK:       else:
 ; CHECK-NEXT:    ret i64 0
 ;



More information about the llvm-commits mailing list