[llvm] [InstCombine] Added optimisation for trunc (Negated Pow2 >> x) to i1 (PR #157998)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 08:55:39 PDT 2025
https://github.com/kper updated https://github.com/llvm/llvm-project/pull/157998
>From 8b1a062f898b8598a8b27d5298f9dbcb90796fa2 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 11 Sep 2025 05:56:09 +0000
Subject: [PATCH 1/2] Added optimisation for trunc (Negated Pow2 >> x) to i1
---
.../InstCombine/InstCombineCasts.cpp | 9 +++
.../test/Transforms/InstCombine/trunc-lshr.ll | 74 +++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index ccf918f0b6dbe..839286ca83ce9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -990,6 +990,15 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
return replaceInstUsesWith(Trunc, Icmp);
}
+ // OP = { lshr, ashr }
+ // trunc ( OP i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is
+ // negative power of 2
+ if (DestWidth == 1 && match(Src, m_Shr(m_NegatedPower2(C1), m_Value(V1)))) {
+ Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero() - 1);
+ Value *Icmp = Builder.CreateICmpUGT(V1, Right);
+ return replaceInstUsesWith(Trunc, Icmp);
+ }
+
return Changed ? &Trunc : nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/trunc-lshr.ll b/llvm/test/Transforms/InstCombine/trunc-lshr.ll
index c443b35cb1c1e..0e996e5d017fe 100644
--- a/llvm/test/Transforms/InstCombine/trunc-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/trunc-lshr.ll
@@ -219,3 +219,77 @@ define i1 @negative_test_fold_ashr(i8 %x) {
%trunc = trunc i8 %ashr to i1
ret i1 %trunc
}
+
+define i1 @fold_lshr_negated_power_of_2(i8 %x) {
+; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %lshr = lshr i8 -16, %x
+ %trunc = trunc i8 %lshr to i1
+ ret i1 %trunc
+}
+
+define i1 @fold_ashr_negated_power_of_2(i8 %x) {
+; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %ashr = ashr i8 -16, %x
+ %trunc = trunc i8 %ashr to i1
+ ret i1 %trunc
+}
+
+define i1 @fold_lshr_negated_power_of_2_multi_use(i8 %x) {
+; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2_multi_use(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -16, [[X]]
+; CHECK-NEXT: call void @use(i8 [[LSHR]])
+; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %lshr = lshr i8 -16, %x
+ call void @use(i8 %lshr)
+ %trunc = trunc i8 %lshr to i1
+ ret i1 %trunc
+}
+
+define i1 @fold_ashr_negated_power_of_2_multi_use(i8 %x) {
+; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2_multi_use(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 -16, [[X]]
+; CHECK-NEXT: call void @use(i8 [[ASHR]])
+; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %ashr = ashr i8 -16, %x
+ call void @use(i8 %ashr)
+ %trunc = trunc i8 %ashr to i1
+ ret i1 %trunc
+}
+
+define i1 @negative_test_fold_lshr_negated_power_of_2(i8 %x) {
+; CHECK-LABEL: define i1 @negative_test_fold_lshr_negated_power_of_2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -17, [[X]]
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[LSHR]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %lshr = lshr i8 -17, %x
+ %trunc = trunc i8 %lshr to i1
+ ret i1 %trunc
+}
+
+define i1 @negative_test_fold_ashr_negated_power_of_2(i8 %x) {
+; CHECK-LABEL: define i1 @negative_test_fold_ashr_negated_power_of_2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ASHR1:%.*]] = lshr i8 -17, [[X]]
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[ASHR1]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC]]
+;
+ %ashr = ashr i8 -17, %x
+ %trunc = trunc i8 %ashr to i1
+ ret i1 %trunc
+}
>From a5f6efb5e336181a3fd6c2481f6ba5fdc23ee4c5 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 11 Sep 2025 15:54:18 +0000
Subject: [PATCH 2/2] [InstCombine] Replaced comparison to uge
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 839286ca83ce9..6a1e17311ec63 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -994,8 +994,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
// trunc ( OP i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is
// negative power of 2
if (DestWidth == 1 && match(Src, m_Shr(m_NegatedPower2(C1), m_Value(V1)))) {
- Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero() - 1);
- Value *Icmp = Builder.CreateICmpUGT(V1, Right);
+ Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero());
+ Value *Icmp = Builder.CreateICmpUGE(V1, Right);
return replaceInstUsesWith(Trunc, Icmp);
}
More information about the llvm-commits
mailing list