[llvm] [InstCombine] Prefer to keep power-of-2 constants when combining ashr exact and slt/ult of a constant (PR #86111)
Alex Bradbury via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 21 05:03:50 PDT 2024
https://github.com/asb updated https://github.com/llvm/llvm-project/pull/86111
>From 3548b6f0ff11cf4bc9e1d07396f16793322fe3c4 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 21 Mar 2024 11:10:06 +0000
Subject: [PATCH 1/2] [InstCombine] Prefer to keep power-of-2 constants when
combining ashr exact and slt/ult of a constant
We have flexibility in what constant to use when combining an `ashr
exact` with a slt or ult of a constant, and it's not possible to revisit
this decision later in the compilation pipeline after the `ashr exact`
is removed. Keeping a constant close to power-of-2 (pow2val + 1) should
be now worse than neutral, and in some cases may allow better codegen
later on for targets that can more cheaply generated power of 2 (which
may be selectable if converting back to setle/setge) or near power of 2
constants.
Alive2: <https://alive2.llvm.org/ce/z/anqsyz> and
<https://alive2.llvm.org/ce/z/AL9P3o>
---
.../Transforms/InstCombine/InstCombineCompares.cpp | 11 +++++++++++
llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll | 4 ++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index db302d7e526844..016b16ec50f8ac 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2482,10 +2482,21 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
// those conditions rather than checking them. This is difficult because of
// undef/poison (PR34838).
if (IsAShr && Shr->hasOneUse()) {
+ if (IsExact && (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT) &&
+ !C.isMinSignedValue() && (C - 1).isPowerOf2()) {
+ // When C - 1 is a power of two and the transform can be legally
+ // performed, prefer this form so the produced constant is close to a
+ // power of two.
+ // icmp slt/ult (ashr exact X, ShAmtC), C
+ // --> icmp slt/ult (C - 1) << ShAmtC) -1
+ APInt ShiftedC = (C - 1).shl(ShAmtVal) + 1;
+ return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
+ }
if (IsExact || Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT) {
// When ShAmtC can be shifted losslessly:
// icmp PRED (ashr exact X, ShAmtC), C --> icmp PRED X, (C << ShAmtC)
// icmp slt/ult (ashr X, ShAmtC), C --> icmp slt/ult X, (C << ShAmtC)
+
APInt ShiftedC = C.shl(ShAmtVal);
if (ShiftedC.ashr(ShAmtVal) == C)
return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
diff --git a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
index 1b8efe4351c6dc..6cdf18d73c9e90 100644
--- a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
@@ -3379,7 +3379,7 @@ define i1 @ashrslt_01_01_exact(i4 %x) {
define i1 @ashrslt_01_02_exact(i4 %x) {
; CHECK-LABEL: @ashrslt_01_02_exact(
-; CHECK-NEXT: [[C:%.*]] = icmp slt i4 [[X:%.*]], 4
+; CHECK-NEXT: [[C:%.*]] = icmp slt i4 [[X:%.*]], 3
; CHECK-NEXT: ret i1 [[C]]
;
%s = ashr exact i4 %x, 1
@@ -3389,7 +3389,7 @@ define i1 @ashrslt_01_02_exact(i4 %x) {
define i1 @ashrslt_01_03_exact(i4 %x) {
; CHECK-LABEL: @ashrslt_01_03_exact(
-; CHECK-NEXT: [[C:%.*]] = icmp slt i4 [[X:%.*]], 6
+; CHECK-NEXT: [[C:%.*]] = icmp slt i4 [[X:%.*]], 5
; CHECK-NEXT: ret i1 [[C]]
;
%s = ashr exact i4 %x, 1
>From a0d036bd652879bf4d42b4a75db668e844a04e1b Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at asbradbury.org>
Date: Thu, 21 Mar 2024 12:03:44 +0000
Subject: [PATCH 2/2] Update
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 016b16ec50f8ac..645fb7ebc75696 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2488,7 +2488,7 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
// performed, prefer this form so the produced constant is close to a
// power of two.
// icmp slt/ult (ashr exact X, ShAmtC), C
- // --> icmp slt/ult (C - 1) << ShAmtC) -1
+ // --> icmp slt/ult X, (C - 1) << ShAmtC) + 1
APInt ShiftedC = (C - 1).shl(ShAmtVal) + 1;
return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
}
More information about the llvm-commits
mailing list