From 8b1a062f898b8598a8b27d5298f9dbcb90796fa2 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 11 Sep 2025 05:56:09 +0000 Subject: [PATCH 1/3] 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 Date: Thu, 11 Sep 2025 15:54:18 +0000 Subject: [PATCH 2/3] [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); } From 3b3e8db316c56d771af89fd760f07a0c10b02fec Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Fri, 12 Sep 2025 05:36:56 +0000 Subject: [PATCH 3/3] [InstCombine] Return object directly --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 6a1e17311ec63..9ca8194b44f8f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -977,8 +977,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { // trunc ( OP i8 C1, V1) to i1 -> icmp eq V1, log_2(C1) iff C1 is power of 2 if (DestWidth == 1 && match(Src, m_Shr(m_Power2(C1), m_Value(V1)))) { Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero()); - Value *Icmp = Builder.CreateICmpEQ(V1, Right); - return replaceInstUsesWith(Trunc, Icmp); + return new ICmpInst(ICmpInst::ICMP_EQ, V1, Right); } // OP = { lshr, ashr } @@ -986,8 +985,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { // power of 2 if (DestWidth == 1 && match(Src, m_Shr(m_LowBitMask(C1), m_Value(V1)))) { Value *Right = ConstantInt::get(V1->getType(), C1->countr_one()); - Value *Icmp = Builder.CreateICmpULT(V1, Right); - return replaceInstUsesWith(Trunc, Icmp); + return new ICmpInst(ICmpInst::ICMP_ULT, V1, Right); } // OP = { lshr, ashr } @@ -995,8 +993,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { // 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()); - Value *Icmp = Builder.CreateICmpUGE(V1, Right); - return replaceInstUsesWith(Trunc, Icmp); + return new ICmpInst(ICmpInst::ICMP_UGE, V1, Right); } return Changed ? &Trunc : nullptr;