[llvm] [CVP]: Fold `icmp eq X, C` to `trunc X to i1` if C=2k+1 and X in [2k, 2k+1] (PR #83829)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 29 09:54:51 PDT 2024
https://github.com/YanWQ-monad updated https://github.com/llvm/llvm-project/pull/83829
>From d4766bd48762d0a475225d7569217888131c4add Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 4 Mar 2024 19:23:02 +0800
Subject: [PATCH 1/7] [CVP]: Add tests from rust-lang/rust#121673
---
.../CorrelatedValuePropagation/icmp.ll | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index b5337b9ddc2487..3a6c247974defd 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -1475,3 +1475,63 @@ entry:
%select = select i1 %cmp1, i1 %cmp2, i1 false
ret i1 %select
}
+
+define i1 @test_icmp_eq_on_valid_bool_range(i8 %x) {
+; CHECK-LABEL: @test_icmp_eq_on_valid_bool_range(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
+; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[X]], 1
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %1 = icmp ult i8 %x, 2
+ br i1 %1, label %bb1, label %bb2
+
+bb2:
+ %2 = tail call i1 @get_bool()
+ br label %bb3
+
+bb1:
+ %3 = icmp eq i8 %x, 1
+ br label %bb3
+
+bb3:
+ %4 = phi i1 [ %3, %bb1 ], [ %2, %bb2 ]
+ ret i1 %4
+}
+
+define i1 @test_icmp_ne_on_valid_bool_range(i8 %x) {
+; CHECK-LABEL: @test_icmp_ne_on_valid_bool_range(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
+; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %1 = icmp ult i8 %x, 2
+ br i1 %1, label %bb1, label %bb2
+
+bb2:
+ %2 = tail call i1 @get_bool()
+ br label %bb3
+
+bb1:
+ %3 = icmp ne i8 %x, 0
+ br label %bb3
+
+bb3:
+ %4 = phi i1 [ %3, %bb1 ], [ %2, %bb2 ]
+ ret i1 %4
+}
>From b8986ff8d12f175125e59fa29ea976f55ac92534 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 4 Mar 2024 19:30:14 +0800
Subject: [PATCH 2/7] [CVP]: Fold `icmp eq X, C` to `trunc X to i1` if C=2k+1
and X in [2k, 2k+1]
---
.../Scalar/CorrelatedValuePropagation.cpp | 36 +++++++++++++++++++
.../CorrelatedValuePropagation/icmp.ll | 8 ++---
llvm/test/Transforms/JumpThreading/pr33917.ll | 8 ++---
3 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index fb334e8292eb18..1ff198927c5510 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -332,6 +332,39 @@ static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
return true;
}
+/// Given an icmp `icmp eq X, C`,
+/// if we already know that C is 2k+1 and X is in [2k, 2k+1],
+/// then we can fold it to `trunc X to i1`.
+static bool processEqualityICmp(CmpInst *Cmp, LazyValueInfo *LVI) {
+ if (Cmp->getType()->isVectorTy() ||
+ !Cmp->getOperand(0)->getType()->isIntegerTy() || !Cmp->isEquality())
+ return false;
+
+ Value *Op0 = Cmp->getOperand(0);
+ Value *Op1 = Cmp->getOperand(1);
+ ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
+ if (!CI)
+ return false;
+
+ ConstantRange Range =
+ LVI->getConstantRangeAtUse(Cmp->getOperandUse(0), /*UndefAllowed*/ true);
+ APInt RangeSize = Range.getUpper() - Range.getLower();
+ APInt Value = CI->getValue();
+ if (RangeSize != 2 || !Range.contains(Value))
+ return false;
+
+ bool ShouldBeOdd = Cmp->getPredicate() == ICmpInst::Predicate::ICMP_EQ;
+ if ((CI->getValue() & 1) == ShouldBeOdd) {
+ IRBuilder<> B{Cmp};
+ auto *Trunc = B.CreateTruncOrBitCast(Op0, Cmp->getType());
+ Cmp->replaceAllUsesWith(Trunc);
+ Cmp->eraseFromParent();
+ return true;
+ }
+
+ return false;
+}
+
static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
if (constantFoldCmp(Cmp, LVI))
return true;
@@ -340,6 +373,9 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
if (processICmp(ICmp, LVI))
return true;
+ if (processEqualityICmp(Cmp, LVI))
+ return true;
+
return false;
}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index 3a6c247974defd..80a3a7e421a137 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -614,10 +614,10 @@ define void @test_cmp_phi(i8 %a) {
; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[P]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i8 [[P]] to i1
; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool()
; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8
-; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT]]
+; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
@@ -1484,7 +1484,7 @@ define i1 @test_icmp_eq_on_valid_bool_range(i8 %x) {
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[X]], 1
+; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
@@ -1514,7 +1514,7 @@ define i1 @test_icmp_ne_on_valid_bool_range(i8 %x) {
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
diff --git a/llvm/test/Transforms/JumpThreading/pr33917.ll b/llvm/test/Transforms/JumpThreading/pr33917.ll
index 7d21a4e1781519..20380c769bf173 100644
--- a/llvm/test/Transforms/JumpThreading/pr33917.ll
+++ b/llvm/test/Transforms/JumpThreading/pr33917.ll
@@ -15,16 +15,16 @@ define void @patatino() personality ptr @rust_eh_personality {
; CHECK-LABEL: @patatino(
; CHECK-NEXT: bb9:
; CHECK-NEXT: [[T9:%.*]] = invoke ptr @foo()
-; CHECK-NEXT: to label [[GOOD:%.*]] unwind label [[BAD:%.*]]
+; CHECK-NEXT: to label [[GOOD:%.*]] unwind label [[BAD:%.*]]
; CHECK: bad:
; CHECK-NEXT: [[T10:%.*]] = landingpad { ptr, i32 }
-; CHECK-NEXT: cleanup
+; CHECK-NEXT: cleanup
; CHECK-NEXT: resume { ptr, i32 } [[T10]]
; CHECK: good:
; CHECK-NEXT: [[T11:%.*]] = icmp ne ptr [[T9]], null
; CHECK-NEXT: [[T12:%.*]] = zext i1 [[T11]] to i64
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[T12]], 1
-; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[DONE:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[T12]] to i1
+; CHECK-NEXT: br i1 [[TMP0]], label [[IF_TRUE:%.*]], label [[DONE:%.*]]
; CHECK: if_true:
; CHECK-NEXT: call void @llvm.assume(i1 [[T11]])
; CHECK-NEXT: br label [[DONE]]
>From c95e410546f89f34eec42441427ec16f2c7cfa5c Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 4 Mar 2024 19:44:54 +0800
Subject: [PATCH 3/7] Fix format
---
llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 1ff198927c5510..29402266f10071 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -374,7 +374,7 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
return true;
if (processEqualityICmp(Cmp, LVI))
- return true;
+ return true;
return false;
}
>From ce4cf635c37e9b5a243212eacd456d97df73298b Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 4 Mar 2024 20:28:19 +0800
Subject: [PATCH 4/7] Refactor the code based on review
---
.../Scalar/CorrelatedValuePropagation.cpp | 72 +++++++++----------
1 file changed, 36 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 29402266f10071..b5fd2a38dd2941 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -34,6 +34,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
@@ -44,6 +45,7 @@
#include <utility>
using namespace llvm;
+using namespace llvm::PatternMatch;
#define DEBUG_TYPE "correlated-value-propagation"
@@ -285,7 +287,41 @@ static bool processPHI(PHINode *P, LazyValueInfo *LVI, DominatorTree *DT,
return Changed;
}
+/// Given an icmp `icmp eq X, C`,
+/// if we already know that C is 2k+1 and X is in [2k, 2k+1],
+/// then we can fold it to `trunc X to i1`.
+static bool processEqualityICmp(ICmpInst *Cmp, LazyValueInfo *LVI) {
+ if (Cmp->getType()->isVectorTy() ||
+ !Cmp->getOperand(0)->getType()->isIntegerTy() || !Cmp->isEquality())
+ return false;
+
+ Value *Op0 = Cmp->getOperand(0);
+ const APInt *RHSC;
+ if (!match(Cmp->getOperand(1), m_APInt(RHSC)))
+ return false;
+
+ ConstantRange Range =
+ LVI->getConstantRangeAtUse(Cmp->getOperandUse(0), /*UndefAllowed*/ true);
+ APInt RangeSize = Range.getUpper() - Range.getLower();
+ if (RangeSize != 2 || !Range.contains(*RHSC))
+ return false;
+
+ bool ShouldBeOdd = Cmp->getPredicate() == ICmpInst::Predicate::ICMP_EQ;
+ if ((*RHSC)[0] == ShouldBeOdd) {
+ IRBuilder<> B{Cmp};
+ Value *Trunc = B.CreateTrunc(Op0, Cmp->getType());
+ Cmp->replaceAllUsesWith(Trunc);
+ Cmp->eraseFromParent();
+ return true;
+ }
+
+ return false;
+}
+
static bool processICmp(ICmpInst *Cmp, LazyValueInfo *LVI) {
+ if (processEqualityICmp(Cmp, LVI))
+ return true;
+
// Only for signed relational comparisons of scalar integers.
if (Cmp->getType()->isVectorTy() ||
!Cmp->getOperand(0)->getType()->isIntegerTy())
@@ -332,39 +368,6 @@ static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
return true;
}
-/// Given an icmp `icmp eq X, C`,
-/// if we already know that C is 2k+1 and X is in [2k, 2k+1],
-/// then we can fold it to `trunc X to i1`.
-static bool processEqualityICmp(CmpInst *Cmp, LazyValueInfo *LVI) {
- if (Cmp->getType()->isVectorTy() ||
- !Cmp->getOperand(0)->getType()->isIntegerTy() || !Cmp->isEquality())
- return false;
-
- Value *Op0 = Cmp->getOperand(0);
- Value *Op1 = Cmp->getOperand(1);
- ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
- if (!CI)
- return false;
-
- ConstantRange Range =
- LVI->getConstantRangeAtUse(Cmp->getOperandUse(0), /*UndefAllowed*/ true);
- APInt RangeSize = Range.getUpper() - Range.getLower();
- APInt Value = CI->getValue();
- if (RangeSize != 2 || !Range.contains(Value))
- return false;
-
- bool ShouldBeOdd = Cmp->getPredicate() == ICmpInst::Predicate::ICMP_EQ;
- if ((CI->getValue() & 1) == ShouldBeOdd) {
- IRBuilder<> B{Cmp};
- auto *Trunc = B.CreateTruncOrBitCast(Op0, Cmp->getType());
- Cmp->replaceAllUsesWith(Trunc);
- Cmp->eraseFromParent();
- return true;
- }
-
- return false;
-}
-
static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
if (constantFoldCmp(Cmp, LVI))
return true;
@@ -373,9 +376,6 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
if (processICmp(ICmp, LVI))
return true;
- if (processEqualityICmp(Cmp, LVI))
- return true;
-
return false;
}
>From b6f4baad6a859602ace85503e99bdb628e24d01f Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 4 Mar 2024 20:28:55 +0800
Subject: [PATCH 5/7] Add a test on wrapped set
---
.../CorrelatedValuePropagation/icmp.ll | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index 80a3a7e421a137..c6cbc75c50db2d 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -1535,3 +1535,37 @@ bb3:
%4 = phi i1 [ %3, %bb1 ], [ %2, %bb2 ]
ret i1 %4
}
+
+define i1 @test_icmp_ne_on_wrapped_set(i8 %x) {
+; CHECK-LABEL: @test_icmp_ne_on_wrapped_set(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i8 [[X:%.*]], -128
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i8 [[X]], 127
+; CHECK-NEXT: [[TMP3:%.*]] = or i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: br i1 [[TMP3]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[TMP4:%.*]] = tail call i1 @get_bool()
+; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[TMP5:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ [[TMP5]], [[BB1]] ], [ [[TMP4]], [[BB2]] ]
+; CHECK-NEXT: ret i1 [[TMP6]]
+;
+ %1 = icmp sle i8 %x, -128
+ %2 = icmp sge i8 %x, 127
+ %3 = or i1 %1, %2
+ br i1 %3, label %bb1, label %bb2
+
+bb2:
+ %4 = tail call i1 @get_bool()
+ br label %bb3
+
+bb1:
+ %5 = icmp eq i8 %x, 127
+ br label %bb3
+
+bb3:
+ %6 = phi i1 [ %5, %bb1 ], [ %4, %bb2 ]
+ ret i1 %6
+}
>From c817b4ff38fa632c21c25eeae3635edf60ecfd36 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Sat, 30 Mar 2024 00:51:13 +0800
Subject: [PATCH 6/7] Pre-commit: add nsw test
---
.../CorrelatedValuePropagation/icmp.ll | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index c6cbc75c50db2d..16fc94a0efb90f 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -1569,3 +1569,37 @@ bb3:
%6 = phi i1 [ %5, %bb1 ], [ %4, %bb2 ]
ret i1 %6
}
+
+define i1 @test_icmp_ne_on_nsw(i8 %x) {
+; CHECK-LABEL: @test_icmp_ne_on_nsw(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i8 [[X:%.*]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i8 [[X]], -1
+; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: br i1 [[TMP3]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[TMP4:%.*]] = tail call i1 @get_bool()
+; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[TMP5:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ [[TMP5]], [[BB1]] ], [ [[TMP4]], [[BB2]] ]
+; CHECK-NEXT: ret i1 [[TMP6]]
+;
+ %1 = icmp sle i8 %x, 0
+ %2 = icmp sge i8 %x, -1
+ %3 = and i1 %1, %2
+ br i1 %3, label %bb1, label %bb2
+
+bb2:
+ %4 = tail call i1 @get_bool()
+ br label %bb3
+
+bb1:
+ %5 = icmp eq i8 %x, -1
+ br label %bb3
+
+bb3:
+ %6 = phi i1 [ %5, %bb1 ], [ %4, %bb2 ]
+ ret i1 %6
+}
>From 9788b82afb7dd778219b47073d53795103d4d8bb Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Sat, 30 Mar 2024 00:53:46 +0800
Subject: [PATCH 7/7] Add nuw flag when possible
---
.../lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 9 +++++++++
llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll | 8 ++++----
llvm/test/Transforms/JumpThreading/pr33917.ll | 2 +-
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index b5fd2a38dd2941..4b6193f0eeb23a 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -310,6 +310,15 @@ static bool processEqualityICmp(ICmpInst *Cmp, LazyValueInfo *LVI) {
if ((*RHSC)[0] == ShouldBeOdd) {
IRBuilder<> B{Cmp};
Value *Trunc = B.CreateTrunc(Op0, Cmp->getType());
+ if (auto *I = dyn_cast<TruncInst>(Trunc)) {
+ // if Range == [0, 1], i.e. the value is already valid boolean
+ if (Range.getLower() == 0)
+ I->setHasNoUnsignedWrap(true);
+ // if Range == [-1, 0]
+ if (Range.getUpper() == 1)
+ I->setHasNoSignedWrap(true);
+ }
+
Cmp->replaceAllUsesWith(Trunc);
Cmp->eraseFromParent();
return true;
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index 16fc94a0efb90f..705b5ecde3ee88 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -614,7 +614,7 @@ define void @test_cmp_phi(i8 %a) {
; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i8 [[P]] to i1
+; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw i8 [[P]] to i1
; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool()
; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT]]
@@ -1484,7 +1484,7 @@ define i1 @test_icmp_eq_on_valid_bool_range(i8 %x) {
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[TMP3:%.*]] = trunc nuw i8 [[X]] to i1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
@@ -1514,7 +1514,7 @@ define i1 @test_icmp_ne_on_valid_bool_range(i8 %x) {
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[TMP3:%.*]] = trunc nuw i8 [[X]] to i1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
@@ -1580,7 +1580,7 @@ define i1 @test_icmp_ne_on_nsw(i8 %x) {
; CHECK-NEXT: [[TMP4:%.*]] = tail call i1 @get_bool()
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[TMP5:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[TMP5:%.*]] = trunc nsw i8 [[X]] to i1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ [[TMP5]], [[BB1]] ], [ [[TMP4]], [[BB2]] ]
diff --git a/llvm/test/Transforms/JumpThreading/pr33917.ll b/llvm/test/Transforms/JumpThreading/pr33917.ll
index 20380c769bf173..664e0e29d074e1 100644
--- a/llvm/test/Transforms/JumpThreading/pr33917.ll
+++ b/llvm/test/Transforms/JumpThreading/pr33917.ll
@@ -23,7 +23,7 @@ define void @patatino() personality ptr @rust_eh_personality {
; CHECK: good:
; CHECK-NEXT: [[T11:%.*]] = icmp ne ptr [[T9]], null
; CHECK-NEXT: [[T12:%.*]] = zext i1 [[T11]] to i64
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[T12]] to i1
+; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw i64 [[T12]] to i1
; CHECK-NEXT: br i1 [[TMP0]], label [[IF_TRUE:%.*]], label [[DONE:%.*]]
; CHECK: if_true:
; CHECK-NEXT: call void @llvm.assume(i1 [[T11]])
More information about the llvm-commits
mailing list