[llvm] [InstCombine] Fold zext(X) + C2 pred C -> X + C3 pred C4 (PR #110511)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 21 01:09:09 PST 2024
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/110511
>From 4b7a4383be4dd7b775a7def50430eacfa1476344 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 30 Sep 2024 20:52:05 +0800
Subject: [PATCH 1/5] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/icmp-add.ll | 96 ++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index dd8e9c1a45ea10..265403f0b0d8ca 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3183,3 +3183,99 @@ define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) {
%cmp2 = icmp ult i8 %add, 2
ret i1 %cmp2
}
+
+define i1 @zext_range_check_ult(i8 %x) {
+; CHECK-LABEL: @zext_range_check_ult(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i8 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ult i32 %add, 3
+ ret i1 %cmp
+}
+
+; TODO: should be canonicalized to (x - 4) u> 2
+define i1 @zext_range_check_ugt(i8 %x) {
+; CHECK-LABEL: @zext_range_check_ugt(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[CONV]], -7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i8 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ugt i32 %add, 2
+ ret i1 %cmp
+}
+
+; TODO: should be canonicalized to (x - 4) u> 2
+define i1 @zext_range_check_ult_alter(i8 %x) {
+; CHECK-LABEL: @zext_range_check_ult_alter(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i8 %x to i32
+ %add = add i32 %conv, -7
+ %cmp = icmp ult i32 %add, -3
+ ret i1 %cmp
+}
+
+define i1 @zext_range_check_mergable(i8 %x) {
+; CHECK-LABEL: @zext_range_check_mergable(
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[ADD]], 3
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X]], 4
+; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP1]]
+; CHECK-NEXT: ret i1 [[COND]]
+;
+ %conv = zext i8 %x to i32
+ %add = add nsw i32 %conv, -4
+ %cmp1 = icmp ult i32 %add, 3
+ %cmp2 = icmp slt i8 %x, 4
+ %cond = select i1 %cmp2, i1 true, i1 %cmp1
+ ret i1 %cond
+}
+
+; Negative tests
+
+define i1 @sext_range_check_ult(i8 %x) {
+; CHECK-LABEL: @sext_range_check_ult(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = sext i8 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ult i32 %add, 3
+ ret i1 %cmp
+}
+
+define i1 @zext_range_check_ult_illegal_type(i7 %x) {
+; CHECK-LABEL: @zext_range_check_ult_illegal_type(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i7 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i7 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ult i32 %add, 3
+ ret i1 %cmp
+}
>From cd86ab258d274d5d78b61977cdef405f16099875 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 30 Sep 2024 21:31:02 +0800
Subject: [PATCH 2/5] [InstCombine] Fold `zext(X) + C2 u< C -> X + trunc(C2) u<
trunc(C)`
---
.../InstCombine/InstCombineCompares.cpp | 20 +++++++++++++++++++
llvm/test/Transforms/InstCombine/icmp-add.ll | 11 +++-------
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index d602a907e72bcd..d81ad1d27d5028 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3183,6 +3183,26 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
Builder.CreateAdd(X, ConstantInt::get(Ty, *C2 - C - 1)),
ConstantInt::get(Ty, ~C));
+ // zext(V) + C2 <u C -> V + trunc(C2) <u trunc(C) iff C2 s<0 && C s>0
+ Value *V;
+ if (Pred == ICmpInst::ICMP_ULT && match(X, m_ZExt(m_Value(V)))) {
+ Type *NewCmpTy = V->getType();
+ unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits();
+ if (shouldChangeType(Ty, NewCmpTy) &&
+ C2->getSignificantBits() <= NewCmpBW &&
+ C.getSignificantBits() <= NewCmpBW) {
+ APInt TruncatedOffset = C2->trunc(NewCmpBW);
+ APInt TruncatedRHS = C.trunc(NewCmpBW);
+ if (TruncatedOffset.isNegative() && TruncatedRHS.isNonNegative()) {
+ Value *TruncatedOffsetV = ConstantInt::get(NewCmpTy, TruncatedOffset);
+ Value *TruncatedRV = ConstantInt::get(NewCmpTy, TruncatedRHS);
+ return new ICmpInst(ICmpInst::ICMP_ULT,
+ Builder.CreateAdd(V, TruncatedOffsetV),
+ TruncatedRV);
+ }
+ }
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 265403f0b0d8ca..6aaea4109adcb8 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3187,9 +3187,8 @@ define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) {
define i1 @zext_range_check_ult(i8 %x) {
; CHECK-LABEL: @zext_range_check_ult(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
+; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[X:%.*]], -4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], 3
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
@@ -3233,11 +3232,7 @@ entry:
define i1 @zext_range_check_mergable(i8 %x) {
; CHECK-LABEL: @zext_range_check_mergable(
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[ADD]], 3
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X]], 4
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7
; CHECK-NEXT: ret i1 [[COND]]
;
%conv = zext i8 %x to i32
>From 6b5d6c95c50ab429c36c3496ebe55e337f972e4d Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 6 Oct 2024 15:26:31 +0800
Subject: [PATCH 3/5] [InstCombine] Convert to using ConstantRange API
---
.../InstCombine/InstCombineCompares.cpp | 31 +++++++++++--------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index d81ad1d27d5028..1442a9daad5ec7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3183,22 +3183,27 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
Builder.CreateAdd(X, ConstantInt::get(Ty, *C2 - C - 1)),
ConstantInt::get(Ty, ~C));
- // zext(V) + C2 <u C -> V + trunc(C2) <u trunc(C) iff C2 s<0 && C s>0
+ // zext(V) + C2 pred C -> V + C3 pred' C4
Value *V;
- if (Pred == ICmpInst::ICMP_ULT && match(X, m_ZExt(m_Value(V)))) {
+ if (match(X, m_ZExt(m_Value(V)))) {
Type *NewCmpTy = V->getType();
+ unsigned CmpBW = Ty->getScalarSizeInBits();
unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits();
- if (shouldChangeType(Ty, NewCmpTy) &&
- C2->getSignificantBits() <= NewCmpBW &&
- C.getSignificantBits() <= NewCmpBW) {
- APInt TruncatedOffset = C2->trunc(NewCmpBW);
- APInt TruncatedRHS = C.trunc(NewCmpBW);
- if (TruncatedOffset.isNegative() && TruncatedRHS.isNonNegative()) {
- Value *TruncatedOffsetV = ConstantInt::get(NewCmpTy, TruncatedOffset);
- Value *TruncatedRV = ConstantInt::get(NewCmpTy, TruncatedRHS);
- return new ICmpInst(ICmpInst::ICMP_ULT,
- Builder.CreateAdd(V, TruncatedOffsetV),
- TruncatedRV);
+ if (shouldChangeType(Ty, NewCmpTy)) {
+ if (auto ZExtCR = CR.exactIntersectWith(ConstantRange(
+ APInt::getZero(CmpBW), APInt::getOneBitSet(CmpBW, NewCmpBW)))) {
+ ConstantRange SrcCR = ZExtCR->truncate(NewCmpBW);
+ CmpInst::Predicate EquivPred;
+ APInt EquivInt;
+ APInt EquivOffset;
+
+ SrcCR.getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
+ return new ICmpInst(
+ EquivPred,
+ EquivOffset.isZero()
+ ? V
+ : Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
+ ConstantInt::get(NewCmpTy, EquivInt));
}
}
}
>From f86d2bc28f2fd342f4d0bc7125f537ffd40f9c18 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 17:00:19 +0800
Subject: [PATCH 4/5] [InstCombine] Address review comments. NFC.
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 1442a9daad5ec7..4be576c8ce3b0f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3190,9 +3190,8 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
unsigned CmpBW = Ty->getScalarSizeInBits();
unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits();
if (shouldChangeType(Ty, NewCmpTy)) {
- if (auto ZExtCR = CR.exactIntersectWith(ConstantRange(
- APInt::getZero(CmpBW), APInt::getOneBitSet(CmpBW, NewCmpBW)))) {
- ConstantRange SrcCR = ZExtCR->truncate(NewCmpBW);
+ if (CR.getActiveBits() <= NewCmpBW) {
+ ConstantRange SrcCR = CR.truncate(NewCmpBW);
CmpInst::Predicate EquivPred;
APInt EquivInt;
APInt EquivOffset;
>From ec1a880bedaee93ceba83398c9a1a0ca25c08628 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 21 Nov 2024 17:08:50 +0800
Subject: [PATCH 5/5] [InstCombine] Add negative tests. NFC.
---
llvm/test/Transforms/InstCombine/icmp-add.ll | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 6aaea4109adcb8..579247aaccf282 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3274,3 +3274,18 @@ entry:
%cmp = icmp ult i32 %add, 3
ret i1 %cmp
}
+
+define i1 @zext_range_check_ult_range_check_failure(i8 %x) {
+; CHECK-LABEL: @zext_range_check_ult_range_check_failure(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 253
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i8 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ult i32 %add, 253
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list