[llvm] 4b483ec - [InstCombine] Fix failure to fold (and %x, (sext i1 %m)) -> (select %m, %x, 0) with multiple uses of %m (#81409)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 19 02:07:20 PST 2024
Author: SahilPatidar
Date: 2024-02-19T11:07:16+01:00
New Revision: 4b483ecd55d7269e8d9af788e823fc9b476b33ce
URL: https://github.com/llvm/llvm-project/commit/4b483ecd55d7269e8d9af788e823fc9b476b33ce
DIFF: https://github.com/llvm/llvm-project/commit/4b483ecd55d7269e8d9af788e823fc9b476b33ce.diff
LOG: [InstCombine] Fix failure to fold (and %x, (sext i1 %m)) -> (select %m, %x, 0) with multiple uses of %m (#81409)
Resolves #81288.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/binop-cast.ll
llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 43a99fc476e823..ba4649e50402af 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2710,7 +2710,7 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
// arm may not be reversible due to poison semantics. Is that a good
// canonicalization?
Value *A, *B;
- if (match(&I, m_c_And(m_OneUse(m_SExt(m_Value(A))), m_Value(B))) &&
+ if (match(&I, m_c_And(m_SExt(m_Value(A)), m_Value(B))) &&
A->getType()->isIntOrIntVectorTy(1))
return SelectInst::Create(A, B, Constant::getNullValue(Ty));
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index c5d8b578b4dc96..ffd8c2a06c86e4 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -1897,14 +1897,14 @@ define i8 @not_ashr_bitwidth_mask_use1(i8 %x, i8 %y) {
ret i8 %r
}
-; negative test - extra use
+; extra use of xor is ok
define i8 @not_ashr_bitwidth_mask_use2(i8 %x, i8 %y) {
; CHECK-LABEL: @not_ashr_bitwidth_mask_use2(
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: [[NOT:%.*]] = sext i1 [[ISNOTNEG]] to i8
; CHECK-NEXT: call void @use8(i8 [[NOT]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[NOT]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNOTNEG]], i8 [[Y:%.*]], i8 0
; CHECK-NEXT: ret i8 [[R]]
;
%sign = ashr i8 %x, 7
@@ -2004,14 +2004,14 @@ define i16 @invert_signbit_splat_mask_use2(i8 %x, i16 %y) {
ret i16 %r
}
-; negative test - extra use
+; extra use of sext is ok
define i16 @invert_signbit_splat_mask_use3(i8 %x, i16 %y) {
; CHECK-LABEL: @invert_signbit_splat_mask_use3(
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: [[S:%.*]] = sext i1 [[ISNOTNEG]] to i16
; CHECK-NEXT: call void @use16(i16 [[S]])
-; CHECK-NEXT: [[R:%.*]] = and i16 [[S]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNOTNEG]], i16 [[Y:%.*]], i16 0
; CHECK-NEXT: ret i16 [[R]]
;
%a = ashr i8 %x, 7
@@ -2854,3 +2854,18 @@ define i32 @add_constant_equal_with_the_top_bit_of_demandedbits_insertpt(i32 %x,
%and = and i32 %or, 24
ret i32 %and
}
+
+define i32 @and_sext_multiuse(i32 %x, i32 %y, i32 %a, i32 %b) {
+; CHECK-LABEL: @and_sext_multiuse(
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[ADD:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 0
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %cmp = icmp sgt i32 %x, %y
+ %sext = sext i1 %cmp to i32
+ %and1 = and i32 %sext, %a
+ %and2 = and i32 %sext, %b
+ %add = add i32 %and1, %and2
+ ret i32 %add
+}
diff --git a/llvm/test/Transforms/InstCombine/binop-cast.ll b/llvm/test/Transforms/InstCombine/binop-cast.ll
index e3345194d0b328..d521a7d5a2b3a1 100644
--- a/llvm/test/Transforms/InstCombine/binop-cast.ll
+++ b/llvm/test/Transforms/InstCombine/binop-cast.ll
@@ -50,7 +50,7 @@ define i32 @and_sext_to_sel_multi_use(i32 %x, i1 %y) {
; CHECK-LABEL: @and_sext_to_sel_multi_use(
; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: call void @use(i32 [[SEXT]])
-; CHECK-NEXT: [[R:%.*]] = and i32 [[SEXT]], [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 [[X:%.*]], i32 0
; CHECK-NEXT: ret i32 [[R]]
;
%sext = sext i1 %y to i32
@@ -326,10 +326,8 @@ define <2 x i32> @and_add_bool_vec_to_select(<2 x i1> %x, <2 x i32> %y) {
; Negative test of and_add_bool_to_select
define i32 @and_add_bool_to_select_multi_use(i1 %x, i32 %y) {
; CHECK-LABEL: @and_add_bool_to_select_multi_use(
-; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: [[MASK:%.*]] = sext i1 [[NOT_X]] to i32
-; CHECK-NEXT: [[RES:%.*]] = and i32 [[MASK]], [[Y:%.*]]
-; CHECK-NEXT: [[RET:%.*]] = add i32 [[RES]], [[MASK]]
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], -1
+; CHECK-NEXT: [[RET:%.*]] = select i1 [[X:%.*]], i32 0, i32 [[TMP1]]
; CHECK-NEXT: ret i32 [[RET]]
;
%val = zext i1 %x to i32
diff --git a/llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll b/llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll
index 94ab50422c4a11..84f6294c3500f8 100644
--- a/llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll
@@ -163,7 +163,7 @@ define i32 @sub_ashr_and_i32_extra_use_ashr(i32 %x, i32 %y, ptr %p) {
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i32
; CHECK-NEXT: store i32 [[SHR]], ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], [[X]]
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 0
; CHECK-NEXT: ret i32 [[AND]]
;
%sub = sub nsw i32 %y, %x
More information about the llvm-commits
mailing list