[llvm] [InstCombine] Fold selection between less than zero and one (PR #69961)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 31 05:02:52 PST 2024
https://github.com/elhewaty updated https://github.com/llvm/llvm-project/pull/69961
>From dd694fde3767c4900732b848b818f4cce6bddfab Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Mon, 23 Oct 2023 21:37:47 +0300
Subject: [PATCH 1/2] [InstCombine] Add test coverage for (A Pred C) ? (A >> BW
- 1) : 1 (NFC)
---
.../Transforms/InstCombine/icmp-select.ll | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 0d723c9df32e2..d7bdf336c122a 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -5,6 +5,73 @@ declare void @use(i8)
declare void @use.i1(i1)
declare i8 @llvm.umin.i8(i8, i8)
+define i32 @test_icmp_select_lte(i32 %x) {
+; CHECK-LABEL: @test_icmp_select_lte(
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1234
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i32 [[LSHR]], i32 1
+; CHECK-NEXT: ret i32 [[RE]]
+;
+ %cmp = icmp slt i32 %x, 1234
+ %lshr = lshr i32 %x, 31
+ %re = select i1 %cmp, i32 %lshr, i32 1
+ ret i32 %re
+}
+
+define i16 @test_icmp_select_sgt(i16 %x) {
+; CHECK-LABEL: @test_icmp_select_sgt(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[X:%.*]], 123
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[X]], 15
+; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i16 [[LSHR]], i16 1
+; CHECK-NEXT: ret i16 [[RE]]
+;
+ %cmp = icmp sgt i16 %x, 123
+ %lshr = lshr i16 %x, 15
+ %re = select i1 %cmp, i16 %lshr, i16 1
+ ret i16 %re
+}
+
+define i8 @test_icmp_select_ugt(i8 %x) {
+; CHECK-LABEL: @test_icmp_select_ugt(
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X]], 7
+; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i8 [[LSHR]], i8 1
+; CHECK-NEXT: ret i8 [[RE]]
+;
+ %cmp = icmp ugt i8 %x, 10
+ %lshr = lshr i8 %x, 7
+ %re = select i1 %cmp, i8 %lshr, i8 1
+ ret i8 %re
+}
+
+define <2 x i32> @test_icmp_select_sge_vector(<2 x i32> %x) {
+; CHECK-LABEL: @test_icmp_select_sge_vector(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 511, i32 511>
+; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
+; CHECK-NEXT: [[RE:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[LSHR]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT: ret <2 x i32> [[RE]]
+;
+ %cmp = icmp sge <2 x i32> %x, <i32 512, i32 512>
+ %lshr = lshr <2 x i32> %x, <i32 31, i32 31>
+ %re = select <2 x i1> %cmp, <2 x i32> %lshr, <2 x i32> <i32 1, i32 1>
+ ret <2 x i32> %re;
+}
+
+define i8 @test_with_more_than_one_use(i8 %x) {
+; CHECK-LABEL: @test_with_more_than_one_use(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 9
+; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X]], 7
+; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i8 [[LSHR]], i8 1
+; CHECK-NEXT: call void @use(i8 [[LSHR]])
+; CHECK-NEXT: ret i8 [[RE]]
+;
+ %cmp = icmp sge i8 %x, 10
+ %lshr = lshr i8 %x, 7
+ %re = select i1 %cmp, i8 %lshr, i8 1
+ call void @use(i8 %lshr)
+ ret i8 %re
+}
+
define i1 @icmp_select_const(i8 %x, i8 %y) {
; CHECK-LABEL: @icmp_select_const(
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
>From 146d548e068e694197d468d5f4b3ce3603db9d76 Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Tue, 30 Jan 2024 22:40:45 +0200
Subject: [PATCH 2/2] [InstCombine] Fold A pred C ? (A >> BW - 1) : 1 -->
ZExt(A pred C ? A < 0 : 1)
---
.../InstCombine/InstCombineSelect.cpp | 19 ++++++++++++++++++
.../Transforms/InstCombine/icmp-select.ll | 20 ++++++++-----------
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 453e4d788705f..9314d8ba4123b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3409,6 +3409,25 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
return replaceOperand(SI, 2, S);
}
+ {
+ // A pred C ? (A >> BW - 1) : 1 --> ZExt(A pred C ? A < 0 : 1)
+ CmpInst::Predicate Pred;
+ Value *A;
+ const APInt *C;
+ if (match(CondVal, m_ICmp(Pred, m_Value(A), m_APInt(C))) &&
+ match(TrueVal,
+ m_LShr(m_Specific(A),
+ m_SpecificInt(A->getType()->getScalarSizeInBits() - 1))) &&
+ match(FalseVal, m_One()) && TrueVal->hasOneUse()) {
+ auto *NewTrue =
+ Builder.CreateICmpSLT(A, ConstantInt::getNullValue(A->getType()));
+ auto *NewFalse = ConstantInt::get(NewTrue->getType(), 1);
+ auto *NewSelect = Builder.CreateSelect(CondVal, NewTrue, NewFalse);
+ auto *ZExt = Builder.CreateZExt(NewSelect, A->getType());
+ return replaceInstUsesWith(SI, ZExt);
+ }
+ }
+
if (Instruction *R = foldSelectOfBools(SI))
return R;
diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index d7bdf336c122a..551f696dcf8b6 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -7,9 +7,8 @@ declare i8 @llvm.umin.i8(i8, i8)
define i32 @test_icmp_select_lte(i32 %x) {
; CHECK-LABEL: @test_icmp_select_lte(
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1234
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i32 [[LSHR]], i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 1233
+; CHECK-NEXT: [[RE:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[RE]]
;
%cmp = icmp slt i32 %x, 1234
@@ -20,9 +19,8 @@ define i32 @test_icmp_select_lte(i32 %x) {
define i16 @test_icmp_select_sgt(i16 %x) {
; CHECK-LABEL: @test_icmp_select_sgt(
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[X:%.*]], 123
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[X]], 15
-; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i16 [[LSHR]], i16 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X:%.*]], 124
+; CHECK-NEXT: [[RE:%.*]] = zext i1 [[CMP]] to i16
; CHECK-NEXT: ret i16 [[RE]]
;
%cmp = icmp sgt i16 %x, 123
@@ -33,9 +31,8 @@ define i16 @test_icmp_select_sgt(i16 %x) {
define i8 @test_icmp_select_ugt(i8 %x) {
; CHECK-LABEL: @test_icmp_select_ugt(
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 10
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X]], 7
-; CHECK-NEXT: [[RE:%.*]] = select i1 [[CMP]], i8 [[LSHR]], i8 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 11
+; CHECK-NEXT: [[RE:%.*]] = zext i1 [[TMP1]] to i8
; CHECK-NEXT: ret i8 [[RE]]
;
%cmp = icmp ugt i8 %x, 10
@@ -46,9 +43,8 @@ define i8 @test_icmp_select_ugt(i8 %x) {
define <2 x i32> @test_icmp_select_sge_vector(<2 x i32> %x) {
; CHECK-LABEL: @test_icmp_select_sge_vector(
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 511, i32 511>
-; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
-; CHECK-NEXT: [[RE:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[LSHR]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 512, i32 512>
+; CHECK-NEXT: [[RE:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
; CHECK-NEXT: ret <2 x i32> [[RE]]
;
%cmp = icmp sge <2 x i32> %x, <i32 512, i32 512>
More information about the llvm-commits
mailing list