[llvm] Match range check pattern with SExt (PR #118910)
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 9 10:57:05 PST 2024
https://github.com/MatzeB updated https://github.com/llvm/llvm-project/pull/118910
>From 689547b2df9826bc7df694a9a15cb1e8eb921a2b Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Thu, 5 Dec 2024 17:49:07 -0800
Subject: [PATCH 1/5] Match range check pattern with SExt
= Background
LLVM optimizes range check patterns like the following:
```
%nn = and i32 %n, 2147483647 ; %nn is non-negative
%a = icmp sge i32 %x, 0
%b = icmp slt i32 %x, %nn
%c = and i1 %a, %b
```
to a single unsigned comparison:
```
%nn = and i32 %n, 2147483647
%c = icmp ult i32 %x, %nn
```
= Extended Pattern
This adds support for an extended version of this pattern where the
upper range is compared with an `sext` value. Example:
```
%nn = and i64 %n, 2147483647
%x_sext = sext i32 %x to i64
%a = icmp sge i32 %x, 0
%b = icmp slt i64 %x_sext, %nn
%c = and i1 %a, %b
```
is now optimized to:
```
%nn = and i64 %n, 2147483647
%x_sext = sext i32 %x to i64
%c = icmp ugt i64 %nn, %x_sext
```
In Alive2: https://alive2.llvm.org/ce/z/Ff7KJ_
---
.../InstCombine/InstCombineAndOrXor.cpp | 21 ++-
.../Transforms/InstCombine/range-check.ll | 120 ++++++++++++++++++
2 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b4033fc2a418a1..dddab2efd80fb9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -695,14 +695,27 @@ Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
Cmp1->getPredicate());
Value *Input = Cmp0->getOperand(0);
+ Value *Cmp1Op0 = Cmp1->getOperand(0);
+ Value *Cmp1Op1 = Cmp1->getOperand(1);
Value *RangeEnd;
- if (Cmp1->getOperand(0) == Input) {
+ if (Cmp1Op0 == Input) {
// For the upper range compare we have: icmp x, n
- RangeEnd = Cmp1->getOperand(1);
- } else if (Cmp1->getOperand(1) == Input) {
+ RangeEnd = Cmp1Op1;
+ } else if (isa<SExtInst>(Cmp1Op0) &&
+ cast<SExtInst>(Cmp1Op0)->getOperand(0) == Input) {
+ // For the upper range compare we have: icmp (sext x), n
+ Input = Cmp1Op0;
+ RangeEnd = Cmp1Op1;
+ } else if (Cmp1Op1 == Input) {
// For the upper range compare we have: icmp n, x
- RangeEnd = Cmp1->getOperand(0);
Pred1 = ICmpInst::getSwappedPredicate(Pred1);
+ RangeEnd = Cmp1Op0;
+ } else if (isa<SExtInst>(Cmp1Op1) &&
+ cast<SExtInst>(Cmp1Op1)->getOperand(0) == Input) {
+ // For the upper range compare we have: icmp n, (sext x)
+ Pred1 = ICmpInst::getSwappedPredicate(Pred1);
+ Input = Cmp1Op1;
+ RangeEnd = Cmp1Op0;
} else {
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/range-check.ll b/llvm/test/Transforms/InstCombine/range-check.ll
index ebb310fb7c1f8f..161fc2d7fdc1dc 100644
--- a/llvm/test/Transforms/InstCombine/range-check.ll
+++ b/llvm/test/Transforms/InstCombine/range-check.ll
@@ -32,6 +32,21 @@ define i1 @test_and1_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_and1_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_and1_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ugt i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sge i32 %x, 0
+ %b = icmp slt i64 %x_sext, %nn
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_and2(i32 %x, i32 %n) {
; CHECK-LABEL: @test_and2(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -60,6 +75,21 @@ define i1 @test_and2_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_and2_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_and2_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp uge i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sgt i32 %x, -1
+ %b = icmp sle i64 %x_sext, %nn
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_and3(i32 %x, i32 %n) {
; CHECK-LABEL: @test_and3(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -86,6 +116,21 @@ define i1 @test_and3_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_and3_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_and3_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ugt i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sgt i64 %nn, %x_sext
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_and4(i32 %x, i32 %n) {
; CHECK-LABEL: @test_and4(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -112,6 +157,21 @@ define i1 @test_and4_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_and4_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_and4_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp uge i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sge i64 %nn, %x_sext
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_or1(i32 %x, i32 %n) {
; CHECK-LABEL: @test_or1(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -140,6 +200,21 @@ define i1 @test_or1_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_or1_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_or1_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ule i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp slt i32 %x, 0
+ %b = icmp sge i64 %x_sext, %nn
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_or2(i32 %x, i32 %n) {
; CHECK-LABEL: @test_or2(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -168,6 +243,21 @@ define i1 @test_or2_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_or2_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_or2_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sle i32 %x, -1
+ %b = icmp sgt i64 %x_sext, %nn
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_or3(i32 %x, i32 %n) {
; CHECK-LABEL: @test_or3(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -194,6 +284,21 @@ define i1 @test_or3_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_or3_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_or3_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ule i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp sle i64 %nn, %x_sext
+ %b = icmp slt i32 %x, 0
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
define i1 @test_or4(i32 %x, i32 %n) {
; CHECK-LABEL: @test_or4(
; CHECK-NEXT: [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -220,6 +325,21 @@ define i1 @test_or4_logical(i32 %x, i32 %n) {
ret i1 %c
}
+define i1 @test_or4_sext(i32 %x, i64 %n) {
+; CHECK-LABEL: @test_or4_sext(
+; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
+; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[NN]], [[X_SEXT]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %nn = and i64 %n, 2147483647
+ %x_sext = sext i32 %x to i64
+ %a = icmp slt i64 %nn, %x_sext
+ %b = icmp slt i32 %x, 0
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
; Negative tests
define i1 @negative1(i32 %x, i32 %n) {
>From db77078bec2f6ece52b6955a117d827c8400b8ee Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Fri, 6 Dec 2024 13:33:17 -0800
Subject: [PATCH 2/5] Address review feedback
---
.../Transforms/InstCombine/InstCombineAndOrXor.cpp | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index dddab2efd80fb9..b607536c2ff976 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -698,20 +698,10 @@ Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
Value *Cmp1Op0 = Cmp1->getOperand(0);
Value *Cmp1Op1 = Cmp1->getOperand(1);
Value *RangeEnd;
- if (Cmp1Op0 == Input) {
- // For the upper range compare we have: icmp x, n
- RangeEnd = Cmp1Op1;
- } else if (isa<SExtInst>(Cmp1Op0) &&
- cast<SExtInst>(Cmp1Op0)->getOperand(0) == Input) {
- // For the upper range compare we have: icmp (sext x), n
+ if (match(Cmp1Op0, m_SExtOrSelf(m_Specific(Input)))) {
Input = Cmp1Op0;
RangeEnd = Cmp1Op1;
- } else if (Cmp1Op1 == Input) {
- // For the upper range compare we have: icmp n, x
- Pred1 = ICmpInst::getSwappedPredicate(Pred1);
- RangeEnd = Cmp1Op0;
- } else if (isa<SExtInst>(Cmp1Op1) &&
- cast<SExtInst>(Cmp1Op1)->getOperand(0) == Input) {
+ } else if (match(Cmp1Op1, m_SExtOrSelf(m_Specific(Input)))) {
// For the upper range compare we have: icmp n, (sext x)
Pred1 = ICmpInst::getSwappedPredicate(Pred1);
Input = Cmp1Op1;
>From 288977872b761c8e17cd1f443c5735f3994d84af Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Fri, 6 Dec 2024 13:35:40 -0800
Subject: [PATCH 3/5] adjust
---
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b607536c2ff976..1ce0aee955015c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -699,13 +699,14 @@ Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
Value *Cmp1Op1 = Cmp1->getOperand(1);
Value *RangeEnd;
if (match(Cmp1Op0, m_SExtOrSelf(m_Specific(Input)))) {
+ // For the upper range compare we have: icmp x, n
Input = Cmp1Op0;
RangeEnd = Cmp1Op1;
} else if (match(Cmp1Op1, m_SExtOrSelf(m_Specific(Input)))) {
// For the upper range compare we have: icmp n, (sext x)
- Pred1 = ICmpInst::getSwappedPredicate(Pred1);
Input = Cmp1Op1;
RangeEnd = Cmp1Op0;
+ Pred1 = ICmpInst::getSwappedPredicate(Pred1);
} else {
return nullptr;
}
>From 76e6a24015d7fca101c9ab14fe704ec28b147e73 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Fri, 6 Dec 2024 14:13:01 -0800
Subject: [PATCH 4/5] Update InstCombineAndOrXor.cpp
---
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 1ce0aee955015c..314b1f0b43e3b5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -703,7 +703,7 @@ Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
Input = Cmp1Op0;
RangeEnd = Cmp1Op1;
} else if (match(Cmp1Op1, m_SExtOrSelf(m_Specific(Input)))) {
- // For the upper range compare we have: icmp n, (sext x)
+ // For the upper range compare we have: icmp n, x
Input = Cmp1Op1;
RangeEnd = Cmp1Op0;
Pred1 = ICmpInst::getSwappedPredicate(Pred1);
>From 107b0e951473fddbff0e0c049618ae737b873f54 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Mon, 9 Dec 2024 10:56:20 -0800
Subject: [PATCH 5/5] Use assume instead of and for the tests
---
.../Transforms/InstCombine/range-check.ll | 64 ++++++++++++-------
1 file changed, 40 insertions(+), 24 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/range-check.ll b/llvm/test/Transforms/InstCombine/range-check.ll
index 161fc2d7fdc1dc..002f0224af6b03 100644
--- a/llvm/test/Transforms/InstCombine/range-check.ll
+++ b/llvm/test/Transforms/InstCombine/range-check.ll
@@ -34,15 +34,17 @@ define i1 @test_and1_logical(i32 %x, i32 %n) {
define i1 @test_and1_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_and1_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ugt i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
%a = icmp sge i32 %x, 0
- %b = icmp slt i64 %x_sext, %nn
+ %b = icmp slt i64 %x_sext, %n
%c = and i1 %a, %b
ret i1 %c
}
@@ -77,15 +79,17 @@ define i1 @test_and2_logical(i32 %x, i32 %n) {
define i1 @test_and2_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_and2_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp uge i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
%a = icmp sgt i32 %x, -1
- %b = icmp sle i64 %x_sext, %nn
+ %b = icmp sle i64 %x_sext, %n
%c = and i1 %a, %b
ret i1 %c
}
@@ -118,14 +122,16 @@ define i1 @test_and3_logical(i32 %x, i32 %n) {
define i1 @test_and3_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_and3_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ugt i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
- %a = icmp sgt i64 %nn, %x_sext
+ %a = icmp sgt i64 %n, %x_sext
%b = icmp sge i32 %x, 0
%c = and i1 %a, %b
ret i1 %c
@@ -159,14 +165,16 @@ define i1 @test_and4_logical(i32 %x, i32 %n) {
define i1 @test_and4_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_and4_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp uge i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
- %a = icmp sge i64 %nn, %x_sext
+ %a = icmp sge i64 %n, %x_sext
%b = icmp sge i32 %x, 0
%c = and i1 %a, %b
ret i1 %c
@@ -202,15 +210,17 @@ define i1 @test_or1_logical(i32 %x, i32 %n) {
define i1 @test_or1_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_or1_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ule i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
%a = icmp slt i32 %x, 0
- %b = icmp sge i64 %x_sext, %nn
+ %b = icmp sge i64 %x_sext, %n
%c = or i1 %a, %b
ret i1 %c
}
@@ -245,15 +255,17 @@ define i1 @test_or2_logical(i32 %x, i32 %n) {
define i1 @test_or2_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_or2_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
%a = icmp sle i32 %x, -1
- %b = icmp sgt i64 %x_sext, %nn
+ %b = icmp sgt i64 %x_sext, %n
%c = or i1 %a, %b
ret i1 %c
}
@@ -286,14 +298,16 @@ define i1 @test_or3_logical(i32 %x, i32 %n) {
define i1 @test_or3_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_or3_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ule i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
- %a = icmp sle i64 %nn, %x_sext
+ %a = icmp sle i64 %n, %x_sext
%b = icmp slt i32 %x, 0
%c = or i1 %a, %b
ret i1 %c
@@ -327,14 +341,16 @@ define i1 @test_or4_logical(i32 %x, i32 %n) {
define i1 @test_or4_sext(i32 %x, i64 %n) {
; CHECK-LABEL: @test_or4_sext(
-; CHECK-NEXT: [[NN:%.*]] = and i64 [[N:%.*]], 2147483647
+; CHECK-NEXT: [[N_NOT_NEGATIVE:%.*]] = icmp sgt i64 [[NN:%.*]], -1
+; CHECK-NEXT: call void @llvm.assume(i1 [[N_NOT_NEGATIVE]])
; CHECK-NEXT: [[X_SEXT:%.*]] = sext i32 [[X:%.*]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[NN]], [[X_SEXT]]
; CHECK-NEXT: ret i1 [[C]]
;
- %nn = and i64 %n, 2147483647
+ %n_not_negative = icmp sge i64 %n, 0
+ call void @llvm.assume(i1 %n_not_negative)
%x_sext = sext i32 %x to i64
- %a = icmp slt i64 %nn, %x_sext
+ %a = icmp slt i64 %n, %x_sext
%b = icmp slt i32 %x, 0
%c = or i1 %a, %b
ret i1 %c
More information about the llvm-commits
mailing list